web-dev-qa-db-ja.com

PostgreSQLがインデックス付き列で順次スキャンを実行するのはなぜですか?

非常に単純な例-1つのテーブル、1つのインデックス、1つのクエリ:

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)

代わりにインデックススキャンを実行しないのはなぜですか?私は何が欠けていますか?

128
Alex Vayda

SELECTがテーブル内のすべての行の約5〜10%を超える値を返す場合、順次スキャンはインデックススキャンよりもはるかに高速です。

これは、インデックススキャンが各行に対して複数IO操作を必要とするためです(インデックス内の行を検索し、ヒープから行を取得します)。順次スキャンでは、各行に単一のIOしか必要ありませんが、ディスク上のブロック(ページ)には複数の行が含まれるため、さらに少ないので、単一のIO操作。

Btw:これは他のDBMSにも当てはまります-「インデックスのみのスキャン」としての一部の最適化は除外されます(ただし、SELECT *では、そのようなDBMSが「インデックスのみのスキャン」に行く可能性は非常に低いです)

193

[〜#〜] analyze [〜#〜] テーブル/データベースでしたか?そして、 統計 はどうですか?年が2009年を超えるレコードが多数ある場合、順次スキャンはインデックススキャンよりも高速になる可能性があります。

12
Frank Heikens

インデックススキャンでは、読み取りヘッドが1つの行から別の行にジャンプします。これは、次の物理ブロックの読み取り(シーケンシャルスキャン)よりも1000倍遅いです。

したがって、(取得するレコードの数* 1000)がレコードの総数よりも少ない場合、インデックススキャンのパフォーマンスは向上します。

0
Gaurav Neema