快速发现PostgreSQL中表的行计数
我需要知道表中的行数来计算百分比。如果总计数大于某个预定义的常数,我将使用常量值。否则,我将使用实际行数。
我可以使用SELECT count(*)FROM表。但是如果我的常数值是500,000,并且我在表中有5,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'; 估计的接近程度取决于你是否足够运行 更好 PostgreSQL Wiki中的文章是有点马虎。它忽略了在一个数据库中可以有多个相同名称的表的可能性 – 在不同的模式中。为了解释: 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; 更快,更简单,更安全,更优雅。参见Object Identifier Types上的手册。 在Postgres 9.4中使用to_regclass(‘myschema.mytable’),以避免无效表名的异常: > How to check if a table exists in a given schema
SELECT 100 * count(*) AS estimate FROM mytable TABLESAMPLE SYSTEM (1); 像@a_horse commented一样,如果pg_class中的统计信息由于某种原因而不够新,则SELECT命令的新添加子句可能很有用。例如: >没有自动真空运行。 这只看到一个随机的n%(在示例中为1)选择块并计数其中的行。更大的样本增加了成本,并减少错误,你的选择。精度取决于更多的因素: >行大小的分布。如果给定块比正常行更宽,则计数比通常低。 在大多数情况下,pg_class的估计将更快更准确。 回答实际问题
是否…
是。您可以使用带有LIMIT的子查询: SELECT count(*) FROM (SELECT 1 FROM token LIMIT 500000) t; Postgres实际上停止计数超过给定的限制,你获得一个精确和当前计数最多n行(在示例中为500000),否则n。没有几乎像pg_class中的估计一样快。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |