Очень простой пример - одна таблица, один индекс, один запрос:
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)
Почему вместо этого он не выполняет сканирование индекса? Чего мне не хватает?
источник
Вы анализировали таблицу / базу данных? А как насчет статистики ? Когда существует много записей, где год> 2009, последовательное сканирование может быть быстрее, чем сканирование индекса.
источник
При индексном сканировании считывающая головка переходит из одной строки в другую, что в 1000 раз медленнее, чем при чтении следующего физического блока (при последовательном сканировании).
Таким образом, если (количество извлекаемых записей * 1000) меньше, чем общее количество записей, сканирование индекса будет работать лучше.
источник
@a_horse_with_no_name объяснил это довольно хорошо. Также, если вы действительно хотите использовать сканирование индекса, вы должны обычно использовать ограниченные диапазоны в предложении where. например - год> 2019 и год <2020.
Часто статистика не обновляется в таблице, и это может быть невозможно из-за ограничений. В этом случае оптимизатор не будет знать, сколько строк он должен занять в году> 2019. Таким образом, он выбирает последовательное сканирование вместо полного знания. Ограниченные перегородки решат проблему большую часть времени.
источник