Ответ
Оптимизатор запросов (Query Optimizer) может отказаться от использования индекса, если сочтет полное сканирование таблицы (Full Table Scan) более эффективным, или если структура запроса делает применение индекса невозможным.
Основные причины:
- Неселективность индекса: Если индекс охватывает слишком большую часть таблицы (обычно >15-30%), сканирование всей таблицы может быть быстрее из-за накладных расходов на случайные чтения.
- Использование функций или выражений в условии WHERE:
-- Индекс по `created_at` не будет использован SELECT * FROM orders WHERE DATE(created_at) = '2023-10-01'; -- Решение: переписать условие SELECT * FROM orders WHERE created_at >= '2023-10-01' AND created_at < '2023-10-02'; - Оператор
LIKEс начальным wildcard-символом:-- Индекс по `name` не используется SELECT * FROM users WHERE name LIKE '%smith%'; -- Индекс МОЖЕТ быть использован SELECT * FROM users WHERE name LIKE 'smith%'; - Несоответствие типов данных (Implicit Casting):
-- Если `phone` — строка, а индекс по `phone`, то индекс может не использоваться SELECT * FROM customers WHERE phone = 1234567; -- Число приводится к строке - Неправильный порядок столбцов в составном индексе: Для индекса
INDEX(col_a, col_b)запрос с условием только поcol_b(WHERE col_b = 5) не сможет его эффективно использовать. - Отсутствие статистики или устаревшая статистика: Оптимизатор принимает решения на основе статистики о распределении данных. Неактуальная статистика ведет к неоптимальному плану запроса.
- Использование
ORс незаиндексированными столбцами: Если в условииORучаствует столбец без индекса, оптимизатор может выбрать полное сканирование. - Запросы, возвращающие очень маленький процент строк: Иногда для очень маленьких таблиц сканирование эффективнее использования индекса.