Ответ
При создании индексов необходимо оценивать несколько ключевых факторов для баланса производительности чтения и записи.
Основные критерии:
-
Селективность столбца
- Высокая селективность (уникальные или почти уникальные значения, например,
id,email) — лучшие кандидаты для индекса. - Низкая селективность (мало уникальных значений, например,
gender,status) — индексы часто неэффективны, может помочь частичный индекс.
- Высокая селективность (уникальные или почти уникальные значения, например,
-
Паттерны запросов
- Индексируйте столбцы, которые часто фигурируют в условиях
WHERE,JOIN,ORDER BYиGROUP BY.
- Индексируйте столбцы, которые часто фигурируют в условиях
-
Композитные (составные) индексы
- Порядок столбцов критически важен. Первым должен идти наиболее селективный столбец, используемый в условиях равенства (
=).-- Эффективный индекс: селективный last_name идёт первым CREATE INDEX idx_users_name_status ON users(last_name, status); -- Менее эффективный индекс CREATE INDEX idx_users_status_name ON users(status, last_name);
- Порядок столбцов критически важен. Первым должен идти наиболее селективный столбец, используемый в условиях равенства (
-
Влияние на операции записи (DML)
- Каждый индекс замедляет
INSERT,UPDATE,DELETE, так как требует дополнительного обновления структур данных.
- Каждый индекс замедляет
-
Типы данных и размер
- Избегайте индексации больших типов (
TEXT,BLOB). Для длинных строк используйте индексы по префиксу или хэшированные значения. - Большие индексы потребляют больше оперативной памяти и дискового пространства.
- Избегайте индексации больших типов (
-
Мониторинг и обслуживание
- Регулярно анализируйте использование индексов (например, через
pg_stat_user_indexesв PostgreSQL) и удаляйте неиспользуемые.
- Регулярно анализируйте использование индексов (например, через
Ответ 18+ 🔞
А, ну вот, опять про индексы, классика жанра! Слушай, это ж как в гараже — можно навесить кучу прибамбасов на тачку, но если не в ту сторону болты крутить, она только громче греметь будет, а ехать — хуй. Так и с базами.
Главная мысль, которую надо вбить себе в башку: индекс — это не волшебная палочка, это инструмент. Им можно гвоздь забить, а можно себе по ебалу получить. Вот на что смотреть, чтобы не получить.
На что орать, когда индекс выбираешь:
-
Селективность, мать её.
- Высокая — это когда значений дохуя разных.
id,email— идеально. База смотрит в индекс и сразу находит одну запись, как будто ты в книге по оглавлению нужную страницу. Красота. - Низкая — это пиздец. Типа
пол(М/Ж) илистатус заказа('новый', 'в работе'). Представь: ты ищешь в книге все слова "и". Да там каждая вторая страница! Такой индекс чаще всего — просто бесполезная трата места, он только мешать будет. Хотя, если очень хочется, можно сделать частичный — типа "индексируй только где status='новый'", это иногда выстреливает.
- Высокая — это когда значений дохуя разных.
-
Куда чаще всего тычешься? Ну серьёзно, подумай головой. Какие поля в
WHERE,JOIN,ORDER BYмелькают? Вот их и индексируй в первую очередь. Индексировать полеcreated_at, по которому раз в год отчёт делают, а поuser_idкаждый запрос фильтрует — это, прости, мудя полная. -
Составные индексы — тут вообще танцы с бубном. Порядок столбцов — это пиздец как важно. Первым идёт тот, по которому ищешь точным совпадением (
=), и желательно самый селективный. Представь телефонную книгу: она отсортирована по (Фамилия, Имя). Найти всех Ивановых — быстро. Найти всех по имени "Петя" — нихуя не быстро, придётся всю книгу листать.-- Так — хорошо. Сначала селективная фамилия. CREATE INDEX idx_users_name_status ON users(last_name, status); -- А так — хуёво. Сначала статус, от которого проку ноль. CREATE INDEX idx_users_status_name ON users(status, last_name); -
За всё хорошее надо платить. Запомни раз и навсегда: каждый индекс замедляет INSERT, UPDATE и DELETE. Потому что когда ты добавляешь запись, база — хорошая девочка — идёт и обновляет все индексы, где эта запись должна быть. Добавил пять индексов — сделал пять лишних записей вместо одной. Это как в квартиру новую вещь поставить: надо не просто на пол кинуть, а на полку, в шкаф, в ящик... Заебешься. Поэтому не накручивай их, как сумасшедший.
-
Размер имеет значение. Индексировать столбец
TEXT, где целые романы хранятся — это идиотизм. Индекс будет размером с оригинальную таблицу, и работать будет через жопу. Для такого есть специальные штуки — индексы по префиксу (первые N символов) или, на крайняк, функциональные индексы (например, на хэш от значения). Большой индекс — много памяти жрёт, на диске места занимает, всё тормозит. -
За ними надо следить, как за тараканами на кухне. Создал и забыл? Нихуя подобного. Со временем запросы меняются, а индексы остаются. Может, какой-то индекс уже год никто не использует, а он место проёбывает. Надо периодически включать мониторинг (в том же PostgreSQL —
pg_stat_user_indexes) и смотреть: а этот, блядь, индекс хоть раз использовался? Если нет — смело в мусорку. И фрагментацию индексов (если СУБД такая) тоже надо чистить, иначе они "разбухают" и тормозят.
Короче, суть в чём: думай, что делаешь. Не лепи индекс на каждое поле, а то получишь базу, которая отлично отвечает на запросы, но добавлять в неё новые данные — это пиздец какой ад. Баланс, епта, везде нужен баланс.