快速发现PostgreSQL中表的行计数

前端之家收集整理的这篇文章主要介绍了快速发现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';

估计的接近程度取决于你是否足够运行ANALYZE。它通常非常接近。
PostgreSQL Wiki FAQ
the dedicated wiki page for count(*) performance

更好

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

TABLESAMPLE SYSTEM (n)在Postgres 9.5

SELECT 100 * count(*) AS estimate FROM mytable TABLESAMPLE SYSTEM (1);

@a_horse commented一样,如果pg_class中的统计信息由于某种原因而不够新,则SELECT命令的新添加子句可能很有用。例如:

>没有自动真空运行。
>在大INSERT或DELETE之后立即。
> TEMPORARY表(不包括自动真空)。

这只看到一个随机的n%(在示例中为1)选择块并计数其中的行。更大的样本增加了成本,并减少错误,你的选择。精度取决于更多的因素:

>行大小的分布。如果给定块比正常行更宽,则计数比通常低。
>死的元组或FILLFACTOR占用每个块的空间。如果在表中不均匀分布,则估计可能关闭
>一般舍入误差。

在大多数情况下,pg_class的估计将更快更准确。

回答实际问题

First,I need to know the number of rows in that table,if the total
count is greater than some predefined constant,

是否…

… is possible at the moment the count pass my constant value,it will
stop the counting (and not wait to finish the counting to inform the
row count is greater).

是。您可以使用带有LIMIT的子查询

SELECT count(*) FROM (SELECT 1 FROM token LIMIT 500000) t;

Postgres实际上停止计数超过给定的限制,你获得一个精确和当前计数最多n行(在示例中为500000),否则n。没有几乎像pg_class中的估计一样快。

猜你在找的Postgre SQL相关文章