Ответ
Индекс — это компромисс между ускорением чтения (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); Ответ 18+ 🔞
О, слушай, а вот тебе про индексы в базах данных, но так, чтобы не уснуть. Это ж как сантехника в доме — работает тихо, никто не замечает, пока всё не пиздец как течёт.
Представь, что индекс — это такой шустрый очкарик-библиотекарь. Он знает, где каждая книжка стоит. Ты спрашиваешь — он сразу несётся и приносит. Но! Каждый раз, когда ты новую книгу на полку ставишь, старую выкидываешь или переставляешь, этому очкарику приходится бегать и переписывать свои умные карточки. Вот и весь компромисс: читает быстро, а вот когда пишешь — он тебе мозги ебёт своей суетой.
И вот, блядь, какие колонки не надо этим библиотекарям-индексам поручать, а то он нихуя не поможет, а только обосрётся:
-
Колонки, где значений — раз-два и обчёлся. Ну, типа
пол('М', 'Ж'),статус('новый', 'в процессе', 'пиздец').
Почему? Да потому что оптимизатор запроса на него посмотрит, хмыкнет и скажет: "Да похуй, проще всю таблицу прочитать, чем по твоим дурацким карточкам бегать". Селективность, блядь, ноль. Полезности — как от козла молока. -
Колонки, которые меняются как перчатки у модницы. Ну,
последний_вход,счётчик_обновлений.
Почему? Каждый раз, когда ты эту хуйню обновляешь, бедному индексу приходится своё аккуратное деревце перестраивать. Это ж пиздец какой труд. Запись будет тормозить, как старый запорожец в горку. -
Огромные текстовые поля или бинарники (
TEXT,BLOB).
Почему? Да представь, ты пытаешься проиндексировать "Войну и мир". Индекс станет размером с ещё одну "Войну и мир", а искать по нему — это пиздец, долго и муторно. Для такого есть спец-инструменты — полнотекстовый поиск. Не лепи сюда обычный индекс, это как молотком гвоздь в бетон забивать. -
Колонки, по которым нихуя не ищут. Серьёзно, если в
WHERE,JOINилиORDER BYэта колонка не фигурирует никогда — зачем ей индекс?
Почему? Он будет просто так на диске лежать, жрать место и каждый раз при вставке новой записи говорить: "Э, я тут тоже, не забудь меня обновить, сука!". Бесполезный нахлебник, ебать его в сраку.
Вот, смотри, пиздатый пример, как делать не надо:
-- Статус заказа. Всего три значения: 'новый', 'в работе', 'пиздец готово'.
-- Такой индекс — это деньги на ветер и лишняя работа для БД.
CREATE INDEX idx_orders_status ON orders(status);
Вот и вся магия, ёпта. Создавай индексы с умом, а не потому что "может, пригодится". Иначе получишь овердохуища индексов, которые только всё замедляют.