为什么在这个简单的查询中 seq-scan 可以比 index-scan 和 index-only-scan 快得多?

Chr*_*ien 3 postgresql performance index postgresql-performance

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

 SELECT COUNT(*) FROM A,B WHERE A.a = B.b
Run Code Online (Sandbox Code Playgroud)

a和b是表A和B的主键,所以a&b上有B索引

默认情况下,PostgreSQL 将在 AB 上使用 seq-scan 并使用 hash join,我强制它执行索引扫描和仅索引扫描。

结果表明,seq scan比其他两个快很多,index-scan和index-only-scan在a,b上做全扫描需要更多的时间。

EXPLAIN ANALYZE SELECT COUNT(*) FROM journal,paper WHERE journal.paper_id = paper.paper_id;

在此处输入图片说明

有人可以解释一下吗?

非常感谢!

Vér*_*ace 5

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

基本上,归结为此处给出的解释。如果表太小,优化器会说“不值得费心去索引,查找然后获取数据,相反,我只是啜饮所有数据并挑选出我需要的东西",即执行 FTS。

[编辑以回答@txsing 的评论]

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

一个优秀的explantion(PostgreSQL的),请点击这里。写这篇文章的人是PostgreSQL的“主要贡献者”(感谢 @dezso 带领我看到那篇文章)。