Вопрос проверяет понимание работы планировщика запросов PostgreSQL и причин, по которым индекс может игнорироваться.
PostgreSQL может не использовать индекс, если считает, что последовательное сканирование быстрее. Это происходит, например, при маленькой таблице, плохой селективности условия или устаревшей статистике. Планировщик оценивает стоимость различных планов и выбирает наиболее дешёвый. Поэтому наличие индекса не гарантирует его использование.
Перед выполнением запроса PostgreSQL использует планировщик (query planner), который:
оценивает возможные варианты выполнения
рассчитывает приблизительную стоимость каждого варианта
выбирает наиболее дешёвый
Индекс используется только тогда, когда его использование дешевле, чем последовательное сканирование (Seq Scan).
Маленький размер таблицы
Если таблица содержит немного строк, быстрее прочитать её полностью, чем выполнять случайные чтения через индекс.
Низкая селективность условия
Если условие возвращает большую часть таблицы, использование индекса не даёт выигрыша.
Пример:
SELECT * FROM users WHERE is_active = true;
Если почти все строки is_active = true, индекс мало помогает.
Устаревшая статистика
Планировщик опирается на статистику. Если она устарела, он может ошибиться.
Решение:
ANALYZE users;
Несоответствие типам или функциям
Если запрос использует выражение:
WHERE LOWER(email) = 'test@example.com'
Обычный индекс на email использоваться не будет, если нет функционального индекса.
Неподходящий тип условия
Например:
использование LIKE '%abc'
неиспользуемые части составного индекса
Используют:
EXPLAIN ANALYZE SELECT ...
Это показывает:
какой план выбран
использовался ли индекс
Понимание поведения индексов необходимо:
при оптимизации медленных запросов
при проектировании схемы БД
при анализе нагрузки
PostgreSQL не обязан использовать индекс. Он выбирает план на основе стоимости, и иногда последовательное сканирование действительно быстрее. Поэтому оптимизация всегда начинается с анализа плана выполнения.