Почему PostgreSQL выполняет последовательное сканирование индексированных столбцов? - PullRequest
127 голосов
/ 05 марта 2011

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

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)

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

Ответы [ 3 ]

190 голосов
/ 05 марта 2011

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

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

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

12 голосов
/ 05 марта 2011

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

0 голосов
/ 01 мая 2019

При индексном сканировании считывание скачков головки с одной строки в другую происходит в 1000 раз медленнее, чем при чтении следующего физического блока (при последовательном сканировании).

Таким образом, если (количество извлекаемых записей * 1000) меньше, чем общее количество записей, сканирование индекса будет работать лучше.

...