从 pg_class.reltuples 获取给定条件下的计数估计值

Chr*_*itt 2 postgresql index count

是否可以reltuples使用附加条件查询给定表的列table.name LIKE 'hello%'

目前在我更大的表上,SELECT count(*)查询需要很长时间,我不需要确切的计数。所以我想知道是否可以WHERE在 the 中添加子句reltuples

Erw*_*ter 9

不是开箱即用的。但是您可以通过...

部分索引

CREATE INDEX tbl_name_hello_idx ON tbl(tbl_id) WHERE name LIKE 'hello%';

SELECT reltuples
FROM   pg_class
WHERE  oid = 'tbl_name_hello_idx'::regclass;  -- or schema-qualify table name
Run Code Online (Sandbox Code Playgroud)

实际的索引列(tbl_id在示例中)无关紧要(除非您对索引有其他用途)。最好选择一个永远不会改变的小列:serialPK 列将是一个完美的候选者。或者您可以使用常量(这会破坏该索引的其他目的):

CREATE INDEX tbl_name_hello_idx ON tbl((1)) WHERE name LIKE 'hello%';
Run Code Online (Sandbox Code Playgroud)

每个索引都有自己的条目pg_classreltuples计数。文档:

reltuples...
表中的行数。这只是规划器使用的估计值。它由VACUUMANALYZE和一些 DDL 命令更新,例如CREATE INDEX.

因此,部分索引可以(ab-)用于获取任何谓词集的计数估计,由 autovacuum 自动更新。或者也许您已经有了索引,因为您无论如何都需要它?

这实际上可能是一个非常聪明的想法。但是你必须权衡成本和收益:对于罕见的情况,部分指数很小,但对于常见的情况,成本会变大。虽然保持最新的统计数据相对便宜,但也不是免费的。

有关的:

TABLESAMPLE SYSTEM (n) 在 Postgres 9.5+

您会喜欢即将发布的 Postgres 9.5 中的新功能,它只查看表中 n % 块的随机样本以进行快速估计。1% 的示例:

SELECT 100 * count(*) AS estimate
FROM   tbl TABLESAMPLE SYSTEM (1)
WHERE  name LIKE 'hello%';
Run Code Online (Sandbox Code Playgroud)

上面已经链接的答案中的详细信息:

给定示例的替代方案

对于给定的示例,name LIKE 'hello%'您无论如何都可以使用正确的索引获得非常快速的精确结果:

CREATE INDEX tbl_name_text_pattern_idx ON tbl(name text_pattern_ops);
Run Code Online (Sandbox Code Playgroud)

细节: