2011-03-05 115 views
90

例子很简单 - 一个表,一个索引,一个查询:为什么PostgreSQL对索引列执行顺序扫描?

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) 

为什么它不执行索引扫描呢? 我错过了什么?

回答

135

如果SELECT返回表中所有行的约5-10%以上,则顺序扫描比索引扫描快得多。

这是因为索引扫描需要几个每个行的IO操作(查找索引中的行,然后从堆中检索行)。而顺序扫描只需要每行有一个IO,或者甚至更少,因为磁盘上的块(页面)包含多行,因此可以通过单个IO操作获取多行。

顺便说一句:这是对其他DBMS以及真实的 - 一些优化,如采取搁置“仅扫描索引”(但对于一个SELECT *这是极不可能这样的DBMS会去的“仅索引扫描”)

+6

5-10%取决于一些配置设置和数据存储。这不是一个硬数字。 – 2011-03-05 13:05:09

+4

@Frank:这就是为什么我说“大约”:)但是,感谢您指出 – 2011-03-05 13:06:27

+0

有趣的是,这为我解释了很多事情:) 事实上,当我选择年份> 2010年,它确实索引扫描。 谢谢! – wajda 2011-03-05 15:24:02

8

您是ANALYZE表/数据库吗?那么statistics呢?当年份> 2009年的记录较多时,顺序扫描可能比索引扫描更快。

相关问题