Очень простой пример - одна таблица, один индекс, один запрос:
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)
Почему он НЕ выполняет сканирование индекса? Что мне не хватает?
Если SELECT возвращает более 5-10% всех строк в таблице, последовательное сканирование выполняется намного быстрее, чем сканирование индекса.
Это связано с тем, что для сканирования индекса требуется несколько операций ввода-вывода для каждой строки (найдите строку в индексе, затем извлеките строку из кучи). В то время как для последовательного сканирования требуется только один IO для каждой строки - или даже меньше, потому что блок (страница) на диске содержит более одной строки, поэтому более одной строки можно извлечь с помощью одной операции ввода-вывода.
Btw: это справедливо и для других СУБД - некоторые оптимизации, такие как "просмотр только индексов", отбираются (но для SELECT * очень маловероятно, чтобы такая СУБД переходила к "проверке только индекса" )
Вы ANALYZE таблицу/базу данных? А как насчет статистики ? Когда есть много записей, где год > 2009, последовательное сканирование может быть быстрее, чем сканирование индекса.