На что обращать внимание при создании индексов в базе данных?

Ответ

При создании индексов необходимо оценивать несколько ключевых факторов для баланса производительности чтения и записи.

Основные критерии:

  1. Селективность столбца

    • Высокая селективность (уникальные или почти уникальные значения, например, id, email) — лучшие кандидаты для индекса.
    • Низкая селективность (мало уникальных значений, например, gender, status) — индексы часто неэффективны, может помочь частичный индекс.
  2. Паттерны запросов

    • Индексируйте столбцы, которые часто фигурируют в условиях WHERE, JOIN, ORDER BY и GROUP BY.
  3. Композитные (составные) индексы

    • Порядок столбцов критически важен. Первым должен идти наиболее селективный столбец, используемый в условиях равенства (=).
      -- Эффективный индекс: селективный last_name идёт первым
      CREATE INDEX idx_users_name_status ON users(last_name, status);
      -- Менее эффективный индекс
      CREATE INDEX idx_users_status_name ON users(status, last_name);
  4. Влияние на операции записи (DML)

    • Каждый индекс замедляет INSERT, UPDATE, DELETE, так как требует дополнительного обновления структур данных.
  5. Типы данных и размер

    • Избегайте индексации больших типов (TEXT, BLOB). Для длинных строк используйте индексы по префиксу или хэшированные значения.
    • Большие индексы потребляют больше оперативной памяти и дискового пространства.
  6. Мониторинг и обслуживание

    • Регулярно анализируйте использование индексов (например, через pg_stat_user_indexes в PostgreSQL) и удаляйте неиспользуемые.

Ответ 18+ 🔞

А, ну вот, опять про индексы, классика жанра! Слушай, это ж как в гараже — можно навесить кучу прибамбасов на тачку, но если не в ту сторону болты крутить, она только громче греметь будет, а ехать — хуй. Так и с базами.

Главная мысль, которую надо вбить себе в башку: индекс — это не волшебная палочка, это инструмент. Им можно гвоздь забить, а можно себе по ебалу получить. Вот на что смотреть, чтобы не получить.

На что орать, когда индекс выбираешь:

  1. Селективность, мать её.

    • Высокая — это когда значений дохуя разных. id, email — идеально. База смотрит в индекс и сразу находит одну запись, как будто ты в книге по оглавлению нужную страницу. Красота.
    • Низкая — это пиздец. Типа пол (М/Ж) или статус заказа ('новый', 'в работе'). Представь: ты ищешь в книге все слова "и". Да там каждая вторая страница! Такой индекс чаще всего — просто бесполезная трата места, он только мешать будет. Хотя, если очень хочется, можно сделать частичный — типа "индексируй только где status='новый'", это иногда выстреливает.
  2. Куда чаще всего тычешься? Ну серьёзно, подумай головой. Какие поля в WHERE, JOIN, ORDER BY мелькают? Вот их и индексируй в первую очередь. Индексировать поле created_at, по которому раз в год отчёт делают, а по user_id каждый запрос фильтрует — это, прости, мудя полная.

  3. Составные индексы — тут вообще танцы с бубном. Порядок столбцов — это пиздец как важно. Первым идёт тот, по которому ищешь точным совпадением (=), и желательно самый селективный. Представь телефонную книгу: она отсортирована по (Фамилия, Имя). Найти всех Ивановых — быстро. Найти всех по имени "Петя" — нихуя не быстро, придётся всю книгу листать.

    -- Так — хорошо. Сначала селективная фамилия.
    CREATE INDEX idx_users_name_status ON users(last_name, status);
    -- А так — хуёво. Сначала статус, от которого проку ноль.
    CREATE INDEX idx_users_status_name ON users(status, last_name);
  4. За всё хорошее надо платить. Запомни раз и навсегда: каждый индекс замедляет INSERT, UPDATE и DELETE. Потому что когда ты добавляешь запись, база — хорошая девочка — идёт и обновляет все индексы, где эта запись должна быть. Добавил пять индексов — сделал пять лишних записей вместо одной. Это как в квартиру новую вещь поставить: надо не просто на пол кинуть, а на полку, в шкаф, в ящик... Заебешься. Поэтому не накручивай их, как сумасшедший.

  5. Размер имеет значение. Индексировать столбец TEXT, где целые романы хранятся — это идиотизм. Индекс будет размером с оригинальную таблицу, и работать будет через жопу. Для такого есть специальные штуки — индексы по префиксу (первые N символов) или, на крайняк, функциональные индексы (например, на хэш от значения). Большой индекс — много памяти жрёт, на диске места занимает, всё тормозит.

  6. За ними надо следить, как за тараканами на кухне. Создал и забыл? Нихуя подобного. Со временем запросы меняются, а индексы остаются. Может, какой-то индекс уже год никто не использует, а он место проёбывает. Надо периодически включать мониторинг (в том же PostgreSQL — pg_stat_user_indexes) и смотреть: а этот, блядь, индекс хоть раз использовался? Если нет — смело в мусорку. И фрагментацию индексов (если СУБД такая) тоже надо чистить, иначе они "разбухают" и тормозят.

Короче, суть в чём: думай, что делаешь. Не лепи индекс на каждое поле, а то получишь базу, которая отлично отвечает на запросы, но добавлять в неё новые данные — это пиздец какой ад. Баланс, епта, везде нужен баланс.