我在用 PostgreSQL 9.4.4. 。我有一个这样的查询:

 SELECT COUNT(*) FROM A,B WHERE A.a = B.b

a和b是表A和B的主键,因此a和b上有B索引

默认情况下,PostgreSQL将在AB上使用seq-scan并使用散列连接,我强制它进行索引扫描和仅索引扫描。

结果表明,seq 扫描比其他两种扫描要快得多,对于索引扫描和仅索引扫描,对 a、b 进行全扫描需要更多时间。

解释分析 SELECT COUNT(*) FROM 期刊,论文 WHERE 期刊.paper_id = paper.paper_id;

enter image description here

有人可以解释一下吗?

太感谢了!

有帮助吗?

解决方案 2

我现在知道原因了。

我需要在使用仅索引扫描之前对表进行清理,否则,如果自上次清理以来修改了足够多的堆页,规划器将不会选择使用仅索引扫描。当仅更改少量页面时,可能会发生仅索引扫描,然后涉及堆获取。

如果我强制它使用仅索引扫描,它将为扫描的每个元组从表中获取数据,这可能会导致巨大的成本。

其他提示

这是一个非常常见的查询(请原谅双关语!:-) )来自运行执行全表扫描(FTS)查询的人,当发布者认为系统应该使用索引时。

基本上,它可以归结为给出的解释 这里. 。如果表太小,优化器会说“不值得费心去索引、查找然后获取数据,相反,我只需吸收所有数据并挑选出我需要的数据” “, IE。执行 FTS。

[编辑回答@txsing的评论]

对于 MVCC (多版本并发控制) 数据库中,您必须在给定时刻遍历每条记录以进行计数 - 这就是为什么 COUNT(*) 对于 MySQL 的 InnoDB 而不是 MyISAM 来说要昂贵得多。

有一个很好的解释(针对 PostgreSQL) 这里. 。写这篇文章的人是“主要贡献者” 到 PostgreSQL(感谢 @dezso 引导我看到那篇文章)。

许可以下: CC-BY-SA归因
不隶属于 dba.stackexchange
scroll top