Как ответить
Индексы в SQL — это отдельные структуры данных (чаще всего B+tree), которые ускоряют поиск строк в таблице. Без индекса база данных при каждом запросе выполняет полное сканирование таблицы (Full Table Scan) — читает все страницы данных подряд. С индексом она находит нужные страницы за логарифмическое время. Плата — замедление вставок и обновлений, а также дополнительное место на диске.
Как это выглядит на практике. Допустим, есть таблица users с миллионом записей и запрос:
SELECT * FROM users WHERE last_name = 'Иванов';Без индекса по last_name база прочитает все строки, проверит условие и вернёт совпадения. С индексом она спустится по дереву к листу, где хранятся ссылки на строки с фамилией «Иванов», и прочитает только эти строки. В B+tree листья связаны в список, поэтому range-запросы (WHERE last_name BETWEEN 'И' AND 'К') тоже работают эффективно.
Основные типы индексов, с которыми сталкивается разработчик:
- B+tree — стандарт для большинства реляционных БД (InnoDB, PostgreSQL). Поддерживает точное совпадение, префиксный поиск, сортировку.
- Уникальный индекс — гарантирует уникальность значений, автоматически создаётся для PRIMARY KEY и UNIQUE-ограничений.
- Составной индекс — на несколько колонок. Важен порядок: индекс на (city, last_name) эффективен для запросов с city, с city+last_name, но не для last_name без city (правило левостороннего префикса).
- Покрывающий индекс — включает все колонки, которые нужны запросу. Тогда БД может вообще не обращаться к таблице, а взять данные из листьев индекса.
- Кластеризованный индекс — в InnoDB первичный ключ является кластеризованным: строки таблицы физически хранятся в листьях B+tree, отсортированные по PK. Вторичные индексы в InnoDB хранят не ссылку на строку, а значение первичного ключа — чтобы потом найти строку через кластеризованный индекс.
Когда индекс не помогает? Если селективность низкая (например, поле gender с двумя значениями) — оптимизатор может решить, что дешевле просканировать всю таблицу. Также индекс бесполезен для LIKE '%текст' (поиск по подстроке без префикса) — тут нужен полнотекстовый индекс. И конечно, частые массовые вставки на таблице с несколькими индексами могут стать узким местом: каждый индекс нужно обновлять.
На собеседовании стоит упомянуть, что смотреть план выполнения (EXPLAIN) — лучший способ понять, используется индекс или нет. И что переиндексация (REBUILD) нужна, если фрагментация превышает 30% — это ускоряет сканирование.