В каких случаях индекс в базе данных может не использоваться оптимизатором?

«В каких случаях индекс в базе данных может не использоваться оптимизатором?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Оптимизатор запросов (Query Optimizer) может отказаться от использования индекса, если сочтет полное сканирование таблицы (Full Table Scan) более эффективным, или если структура запроса делает применение индекса невозможным.

Основные причины:

  1. Неселективность индекса: Если индекс охватывает слишком большую часть таблицы (обычно >15-30%), сканирование всей таблицы может быть быстрее из-за накладных расходов на случайные чтения.
  2. Использование функций или выражений в условии 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';
  3. Оператор LIKE с начальным wildcard-символом:
    -- Индекс по `name` не используется
    SELECT * FROM users WHERE name LIKE '%smith%';
    -- Индекс МОЖЕТ быть использован
    SELECT * FROM users WHERE name LIKE 'smith%';
  4. Несоответствие типов данных (Implicit Casting):
    -- Если `phone` — строка, а индекс по `phone`, то индекс может не использоваться
    SELECT * FROM customers WHERE phone = 1234567; -- Число приводится к строке
  5. Неправильный порядок столбцов в составном индексе: Для индекса INDEX(col_a, col_b) запрос с условием только по col_b (WHERE col_b = 5) не сможет его эффективно использовать.
  6. Отсутствие статистики или устаревшая статистика: Оптимизатор принимает решения на основе статистики о распределении данных. Неактуальная статистика ведет к неоптимальному плану запроса.
  7. Использование OR с незаиндексированными столбцами: Если в условии OR участвует столбец без индекса, оптимизатор может выбрать полное сканирование.
  8. Запросы, возвращающие очень маленький процент строк: Иногда для очень маленьких таблиц сканирование эффективнее использования индекса.