Какие типы данных или колонок в базах данных не стоит индексировать?

Ответ

Индекс — это компромисс между ускорением чтения (SELECT) и замедлением записи (INSERT, UPDATE, DELETE). Не стоит создавать индексы для следующих колонок:

  1. Колонки с низкой кардинальностью (селективностью):

    • Что это: Колонки, в которых очень мало уникальных значений (например, пол, is_active, статусы с 2-3 вариантами).
    • Почему: Оптимизатор запросов, скорее всего, проигнорирует такой индекс, так как полное сканирование таблицы (Table Scan) будет быстрее, чем чтение индекса и последующий поиск строк по указателям.
  2. Часто обновляемые колонки:

    • Что это: Поля, которые меняются при каждой или почти каждой операции. Например, last_login_at или счетчик updates_count.
    • Почему: Каждая операция INSERT, UPDATE или DELETE потребует не только изменения данных в таблице, но и перестройки B-дерева индекса, что создает значительные накладные расходы на запись.
  3. Большие текстовые или бинарные поля (TEXT, BLOB):

    • Что это: Колонки для хранения больших объемов текста или файлов.
    • Почему: Индексирование таких полей неэффективно из-за их размера. Индекс получится огромным, а сравнение строк — медленным. Для поиска по таким полям следует использовать специализированные инструменты, например, полнотекстовые индексы (Full-Text Search).
  4. Колонки, не используемые в WHERE, JOIN или ORDER BY:

    • Что это: Поля, по которым никогда не происходит фильтрация, соединение таблиц или сортировка.
    • Почему: Такой индекс будет занимать место на диске и замедлять операции записи, не принося при этом никакой пользы для производительности чтения. Это бесполезная трата ресурсов.

Плохой пример:

-- Статус имеет всего несколько значений: 'new', 'in_progress', 'done'.
-- Этот индекс, скорее всего, будет неэффективен.
CREATE INDEX idx_orders_status ON orders(status);

Ответ 18+ 🔞

О, слушай, а вот тебе про индексы в базах данных, но так, чтобы не уснуть. Это ж как сантехника в доме — работает тихо, никто не замечает, пока всё не пиздец как течёт.

Представь, что индекс — это такой шустрый очкарик-библиотекарь. Он знает, где каждая книжка стоит. Ты спрашиваешь — он сразу несётся и приносит. Но! Каждый раз, когда ты новую книгу на полку ставишь, старую выкидываешь или переставляешь, этому очкарику приходится бегать и переписывать свои умные карточки. Вот и весь компромисс: читает быстро, а вот когда пишешь — он тебе мозги ебёт своей суетой.

И вот, блядь, какие колонки не надо этим библиотекарям-индексам поручать, а то он нихуя не поможет, а только обосрётся:

  1. Колонки, где значений — раз-два и обчёлся. Ну, типа пол ('М', 'Ж'), статус ('новый', 'в процессе', 'пиздец').
    Почему? Да потому что оптимизатор запроса на него посмотрит, хмыкнет и скажет: "Да похуй, проще всю таблицу прочитать, чем по твоим дурацким карточкам бегать". Селективность, блядь, ноль. Полезности — как от козла молока.

  2. Колонки, которые меняются как перчатки у модницы. Ну, последний_вход, счётчик_обновлений.
    Почему? Каждый раз, когда ты эту хуйню обновляешь, бедному индексу приходится своё аккуратное деревце перестраивать. Это ж пиздец какой труд. Запись будет тормозить, как старый запорожец в горку.

  3. Огромные текстовые поля или бинарники (TEXT, BLOB).
    Почему? Да представь, ты пытаешься проиндексировать "Войну и мир". Индекс станет размером с ещё одну "Войну и мир", а искать по нему — это пиздец, долго и муторно. Для такого есть спец-инструменты — полнотекстовый поиск. Не лепи сюда обычный индекс, это как молотком гвоздь в бетон забивать.

  4. Колонки, по которым нихуя не ищут. Серьёзно, если в WHERE, JOIN или ORDER BY эта колонка не фигурирует никогда — зачем ей индекс?
    Почему? Он будет просто так на диске лежать, жрать место и каждый раз при вставке новой записи говорить: "Э, я тут тоже, не забудь меня обновить, сука!". Бесполезный нахлебник, ебать его в сраку.

Вот, смотри, пиздатый пример, как делать не надо:

-- Статус заказа. Всего три значения: 'новый', 'в работе', 'пиздец готово'.
-- Такой индекс — это деньги на ветер и лишняя работа для БД.
CREATE INDEX idx_orders_status ON orders(status);

Вот и вся магия, ёпта. Создавай индексы с умом, а не потому что "может, пригодится". Иначе получишь овердохуища индексов, которые только всё замедляют.