我需要知道表中的行数来计算百分比。如果总数大于某个预定义的常量,我将使用常量值。否则,我将使用实际的行数。

我可以使用SELECT count(*) FROM表。但是,如果我的常量值是500,000,并且我的表中有5,000,000,000行,计算所有行将浪费大量时间。

是否有可能在我的常数值被超过时就停止计数?

我需要精确的行数,只要它低于给定的限制。否则,如果计数超过极限,我将使用极限值,并希望尽快得到答案。

就像这样:

SELECT text,count(*), percentual_calculus()  
FROM token  
GROUP BY text  
ORDER BY count DESC;

当前回答

在Oracle中,可以使用rownum限制返回的行数。我猜类似的构造也存在于其他sql中。所以,对于你给出的例子,你可以限制返回的行数为500001,然后应用一个count(*):

SELECT (case when cnt > 500000 then 500000 else cnt end) myCnt
FROM (SELECT count(*) cnt FROM table WHERE rownum<=500001)

其他回答

在Oracle中,可以使用rownum限制返回的行数。我猜类似的构造也存在于其他sql中。所以,对于你给出的例子,你可以限制返回的行数为500001,然后应用一个count(*):

SELECT (case when cnt > 500000 then 500000 else cnt end) myCnt
FROM (SELECT count(*) cnt FROM table WHERE rownum<=500001)

我曾经在postgres应用程序中运行:

EXPLAIN SELECT * FROM foo;

然后用正则表达式或类似的逻辑检查输出。对于一个简单的SELECT *,输出的第一行应该是这样的:

Seq Scan on uids  (cost=0.00..1.21 rows=8 width=75)

您可以使用rows=(\d+)值作为将返回的行数的粗略估计,然后仅在估计值小于1.5倍阈值(或您认为对应用程序有意义的任何数字)时执行实际的SELECT COUNT(*)。

根据查询的复杂程度,这个数字可能会越来越不准确。事实上,在我的应用程序中,当我们添加连接和复杂条件时,它变得非常不准确,甚至不知道在100的幂范围内我们会返回多少行,所以我们不得不放弃这种策略。

但是,如果您的查询足够简单,Pg可以在合理的误差范围内预测它将返回多少行,那么它可能适合您。

SELECT MAX(id) FROM <table_name>;将id更改为表的PK

参考资料来自本博客。

您可以使用下面的查询来查找行数。

使用pg_class:

 SELECT reltuples::bigint AS EstimatedCount
    FROM   pg_class
    WHERE  oid = 'public.TableName'::regclass;

使用pg_stat_user_tables:

SELECT 
    schemaname
    ,relname
    ,n_live_tup AS EstimatedCount 
FROM pg_stat_user_tables 
ORDER BY n_live_tup DESC;

文本列有多宽?

使用GROUP BY,您无法避免数据扫描(至少是索引扫描)。

我建议:

如果可能,更改模式以删除文本数据的重复。这样,计数将发生在'many'表中的一个狭窄的外键字段上。 或者,用文本的HASH创建一个生成的列,然后GROUP BY哈希列。 同样,这是为了减少工作负载(通过窄列索引进行扫描)

编辑:

你最初的问题与你的编辑不太匹配。我不确定你是否意识到,当与GROUP BY一起使用时,COUNT将返回每个组的项目计数,而不是整个表中的项目计数。