我需要知道表中的行数以计算百分比。如果总计数大于某个预定义常数,我将使用该常数值。否则,我将使用实际的行数。
我可以用SELECT count(*) FROM table
。但是,如果我的常量值为500,000,并且表中有5,000,000,000行,则对所有行进行计数将浪费大量时间。
一旦超过我的恒定值,是否可以停止计数?
我只需要确切的行数,只要它低于给定的限制即可。否则,如果计数超出限制,我将改用限制值,并希望尽快给出答案。
像这样:
SELECT text,count(*), percentual_calculus()
FROM token
GROUP BY text
ORDER BY count DESC;
在PostgreSQL中,对大表中的行进行计数是很慢的。为了获得准确的数字,由于MVCC的性质,它必须对行进行完整计数。有一种方法来大大加快这如果计数也没有必须要确切喜欢它似乎是在你的情况。
而不是获得确切的计数(大表比较慢):
SELECT count(*) AS exact_count FROM myschema.mytable;
您会得到如下估算值(非常快):
SELECT reltuples::bigint AS estimate FROM pg_class where relname='mytable';
估算的接近程度取决于您是否运行ANALYZE
足够。通常很近。
请参阅PostgreSQL Wiki FAQ。
或用于count(*)性能的专用Wiki页面。
PostgreSQL的维基文章 的 是一个有点草率。它忽略了一个数据库中可能存在多个具有相同名称的表的可能性-处于不同的模式。要说明这一点:
SELECT c.reltuples::bigint AS estimate
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = 'mytable'
AND n.nspname = 'myschema'
SELECT reltuples::bigint AS estimate
FROM pg_class
WHERE oid = 'myschema.mytable'::regclass;
更快,更简单,更安全,更优雅。请参阅“对象标识符类型”手册。
to_regclass('myschema.mytable')
在Postgres 9.4+中使用可避免无效表名的例外情况:
TABLESAMPLE SYSTEM (n)
在Postgres 9.5+SELECT 100 * count(*) AS estimate FROM mytable TABLESAMPLE SYSTEM (1);
就像@a_horse commented一样,SELECT
如果pg_class
由于某些原因当前的统计信息不足,则为该命令新添加的子句可能很有用。例如:
autovacuum
运行。INSERT
或DELETE
。TEMPORARY
表格(未被涵盖autovacuum
)。这只会查看随机的n%(1
在示例中)选择的块并计算其中的行。选择更大的样本会增加成本并减少错误。准确性取决于更多因素:
FILLFACTOR
每个块占用空间。如果整个表分布不均,则估计值可能会不正确。在大多数情况下,来自的估计pg_class
会更快,更准确。
首先,我需要知道该表中的行数,如果总计数大于某个预定义常量,
以及是否...
...当计数超过我的常数值时是可能的,它将停止计数(而不是等待完成计数以告知行计数更大)。
是。您可以将子查询与结合使用LIMIT
:
SELECT count(*) FROM (SELECT 1 FROM token LIMIT 500000) t;
Postgres实际上停止计数超过给定的限制,您将获得多达n行(在本示例中为500000)的准确和当前计数,否则为n。但是,速度不及中的估算速度。pg_class
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句