Почему PostgreSQL выполняет последовательное сканирование индексированных столбцов?

106

Очень простой пример - одна таблица, один индекс, один запрос:

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)

Почему он НЕ выполняет сканирование индекса? Что мне не хватает?

Теги:
indexing
sequence

2 ответа

161
Лучший ответ

Если SELECT возвращает более 5-10% всех строк в таблице, последовательное сканирование выполняется намного быстрее, чем сканирование индекса.

Это связано с тем, что для сканирования индекса требуется несколько операций ввода-вывода для каждой строки (найдите строку в индексе, затем извлеките строку из кучи). В то время как для последовательного сканирования требуется только один IO для каждой строки - или даже меньше, потому что блок (страница) на диске содержит более одной строки, поэтому более одной строки можно извлечь с помощью одной операции ввода-вывода.

Btw: это справедливо и для других СУБД - некоторые оптимизации, такие как "просмотр только индексов", отбираются (но для SELECT * очень маловероятно, чтобы такая СУБД переходила к "проверке только индекса" )

  • 10
    5-10% зависит от пары параметров конфигурации и хранения данных. Это не сложный номер.
  • 6
    @Frank: вот почему я сказал «примерно» :) Но спасибо, что указал на это
Показать ещё 8 комментариев
10

Вы ANALYZE таблицу/базу данных? А как насчет статистики ? Когда есть много записей, где год > 2009, последовательное сканирование может быть быстрее, чем сканирование индекса.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню