Ответ
Индекс — это компромисс между ускорением чтения (SELECT
) и замедлением записи (INSERT
, UPDATE
, DELETE
). Не стоит создавать индексы для следующих колонок:
Колонки с низкой кардинальностью (селективностью):
- Что это: Колонки, в которых очень мало уникальных значений (например,
пол
,is_active
, статусы с 2-3 вариантами). - Почему: Оптимизатор запросов, скорее всего, проигнорирует такой индекс, так как полное сканирование таблицы (Table Scan) будет быстрее, чем чтение индекса и последующий поиск строк по указателям.
- Что это: Колонки, в которых очень мало уникальных значений (например,
Часто обновляемые колонки:
- Что это: Поля, которые меняются при каждой или почти каждой операции. Например,
last_login_at
или счетчикupdates_count
. - Почему: Каждая операция
INSERT
,UPDATE
илиDELETE
потребует не только изменения данных в таблице, но и перестройки B-дерева индекса, что создает значительные накладные расходы на запись.
- Что это: Поля, которые меняются при каждой или почти каждой операции. Например,
Большие текстовые или бинарные поля (
TEXT
,BLOB
):- Что это: Колонки для хранения больших объемов текста или файлов.
- Почему: Индексирование таких полей неэффективно из-за их размера. Индекс получится огромным, а сравнение строк — медленным. Для поиска по таким полям следует использовать специализированные инструменты, например, полнотекстовые индексы (Full-Text Search).
Колонки, не используемые в
WHERE
,JOIN
илиORDER BY
:- Что это: Поля, по которым никогда не происходит фильтрация, соединение таблиц или сортировка.
- Почему: Такой индекс будет занимать место на диске и замедлять операции записи, не принося при этом никакой пользы для производительности чтения. Это бесполезная трата ресурсов.
Плохой пример:
-- Статус имеет всего несколько значений: 'new', 'in_progress', 'done'.
-- Этот индекс, скорее всего, будет неэффективен.
CREATE INDEX idx_orders_status ON orders(status);