Ren*_*ani 89 sql postgresql row count
我需要知道表中的行数来计算百分比.如果总计数大于某个预定义常量,我将使用常量值.否则,我将使用实际的行数.
我可以用SELECT count(*) FROM table
.但是如果我的常量值是500,000并且我的表中有5,000,000,000行,那么计算所有行会浪费很多时间.
一旦超过常数值,是否可以停止计数?
只要它低于给定的限制,我只需要确切的行数.否则,如果计数高于限制,我会使用限制值,并希望尽快得到答案.
像这样的东西:
SELECT text,count(*), percentual_calculus()
FROM token
GROUP BY text
ORDER BY count DESC;
Run Code Online (Sandbox Code Playgroud)
Erw*_*ter 191
在PostgreSQL中,已知大表中的行计数速度很慢.为了获得精确的数字,由于MVCC的性质,它必须完整地计算行数.有一种方法来大大加快这如果计数也没有必须要确切喜欢它似乎是在你的情况.
而不是获得准确的计数(大表慢):
SELECT count(*) AS exact_count FROM myschema.mytable;
Run Code Online (Sandbox Code Playgroud)
你得到这样的近似估计(非常快):
SELECT reltuples::bigint AS estimate FROM pg_class where relname='mytable';
Run Code Online (Sandbox Code Playgroud)
估计的接近程度取决于您是否ANALYZE
足够运行.它通常非常接近.
请参阅PostgreSQL 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'
Run Code Online (Sandbox Code Playgroud)
SELECT reltuples::bigint AS estimate
FROM pg_class
WHERE oid = 'myschema.mytable'::regclass;
Run Code Online (Sandbox Code Playgroud)
更快,更简单,更安全,更优雅.请参阅对象标识符类型手册.
to_regclass('myschema.mytable')
在Postgres 9.4+中使用以避免无效表名的例外:
TABLESAMPLE SYSTEM (n)
在Postgres 9.5+SELECT 100 * count(*) AS estimate FROM mytable TABLESAMPLE SYSTEM (1);
Run Code Online (Sandbox Code Playgroud)
像@a_horse评论的那样,SELECT
如果pg_class
由于某种原因统计信息不够充分,那么新添加的命令子句可能会很有用.例如:
autovacuum
跑.INSERT
或后立即DELETE
.TEMPORARY
表格(未涵盖autovacuum
).这仅查看随机n%(1
在示例中)块的选择并计算其中的行.更大的样本会增加成本并减少错误.准确性取决于更多因素:
FILLFACTOR
每个块都有死元组或占用空间.如果在桌子上分布不均匀,估计可能会被取消.在大多数情况下,估计pg_class
将更快,更准确.
首先,我需要知道该表中的行数,如果总计数大于某个预定义的常量,
无论是......
......当计数通过我的常量值时,它可能会停止计数(而不是等待完成计数以通知行计数更大).
是.您可以使用子查询LIMIT
:
SELECT count(*) FROM (SELECT 1 FROM token LIMIT 500000) t;
Run Code Online (Sandbox Code Playgroud)
Postgres 实际上停止计数超出给定的限制,你得到最多n行的精确和当前计数(在示例中为500000),否则为n.然而,并不像估计的那么快.pg_class
Fli*_*mzy 11
我在postgres应用程序中执行了一次运行:
EXPLAIN SELECT * FROM foo;
Run Code Online (Sandbox Code Playgroud)
然后使用正则表达式或类似逻辑检查输出.对于一个简单的SELECT*,第一行输出应该如下所示:
Seq Scan on uids (cost=0.00..1.21 rows=8 width=75)
Run Code Online (Sandbox Code Playgroud)
您可以使用该rows=(\d+)
值作为将返回的行数的粗略估计,然后仅SELECT COUNT(*)
在估计值小于1.5倍阈值(或您认为对您的应用程序有意义的任何数字)时执行.
根据查询的复杂程度,此数字可能会变得越来越不准确.事实上,在我的应用程序中,当我们添加连接和复杂条件时,它变得非常不准确,它完全没有价值,甚至知道如何在100的幂内我们返回多少行,所以我们不得不放弃该策略.
但是如果你的查询很简单,Pg可以在一定的合理误差范围内预测它将返回多少行,它可能对你有用.
您可以使用下面的查询来查找行数。
使用 pg_class:
SELECT reltuples::bigint AS EstimatedCount
FROM pg_class
WHERE oid = 'public.TableName'::regclass;
Run Code Online (Sandbox Code Playgroud)
使用 pg_stat_user_tables:
SELECT
schemaname
,relname
,n_live_tup AS EstimatedCount
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
74440 次 |
最近记录: |