非常简单的例子 - 一个表,一个索引,一个查询:
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极不可能用于“仅索引扫描”)
你ANALYZE表/数据库?那statistics呢?当年份> 2009年有许多记录时,顺序扫描可能比索引扫描更快。
在索引扫描中,读取头从一行跳到另一行,这比读取下一个物理块(在顺序扫描中)慢1000倍。
因此,如果(要检索的记录数* 1000)小于记录总数,则索引扫描将表现更好。