Ответ
Основные причины и диагностика:
-
Полное сканирование выгоднее:
- Для маленьких таблиц или условий с низкой селективностью (>15-30% строк) сканирование таблицы (TABLE SCAN) часто быстрее. Проверить можно через
EXPLAIN ANALYZE:EXPLAIN ANALYZE SELECT * FROM users WHERE status = 'inactive';
- Для маленьких таблиц или условий с низкой селективностью (>15-30% строк) сканирование таблицы (TABLE SCAN) часто быстрее. Проверить можно через
-
Несоответствие типов данных:
- Неявное преобразование типов, например, сравнение строкового поля с числом (
WHERE string_column = 123), блокирует использование индекса.
- Неявное преобразование типов, например, сравнение строкового поля с числом (
-
Использование функций или выражений:
- Индекс не используется, если столбец участвует в выражении:
WHERE UPPER(name) = 'JOHN'илиWHERE price + tax > 100. Решение: переписать запрос или создать функциональный индекс.
- Индекс не используется, если столбец участвует в выражении:
-
Устаревшая статистика:
- Планировщик принимает решение на основе статистики. Если она устарела, решение может быть неоптимальным. Обновить:
ANALYZE TABLE table_name;(илиUPDATE STATISTICS).
- Планировщик принимает решение на основе статистики. Если она устарела, решение может быть неоптимальным. Обновить:
-
Проблема с составным индексом:
- Составной индекс
(A, B, C)не будет использован для условия только поBилиC. Порядок столбцов в индексе должен соответствовать условиям вWHEREиORDER BY.
- Составной индекс
-
Параметризованные запросы и «проблема параметра»:
- При использовании подготовленных выражений (prepared statements) с параметрами планировщик может использовать усредненную статистику. В некоторых СУБД помогает
OPTION (RECOMPILE)или использование литералов для отладки.
- При использовании подготовленных выражений (prepared statements) с параметрами планировщик может использовать усредненную статистику. В некоторых СУБД помогает