非常简单的例子——一张表,一张索引,一次查询:
CREATE TABLE book ( id bigserial NOT NULL, "year" integer, -- other columns... ); CREATE INDEX book_year_idx ON book (year) EXPLAIN SELECT * FROM book b WHERE b.year > 2009
给我:
Seq Scan on book b (cost=0.00..25663.80 rows=105425 width=622) Filter: (year > 2009)
为什么它不执行索引扫描?我错过了什么?
如果 SELECT 返回表中所有行的大约 5-10% 以上,则顺序扫描比索引扫描快得多。
这是因为索引扫描需要对每一行进行 多次 IO 操作(在索引中查找该行,然后从堆中检索该行)。而顺序扫描每行只需要一个 IO - 甚至更少,因为磁盘上的一个块(页)包含多行,因此可以通过单个 IO 操作获取多行。
顺便说一句:这对于其他 DBMS 也是如此 - 一些优化作为“仅索引扫描”被搁置(但对于 SELECT *,这样的 DBMS 极不可能进行“仅索引扫描”)