Составные индексы: индекс по нескольким столбцам

Почему один индекс — это хорошо, а два — лучше? 🔥

Обычные индексы — как соло-исполнители: работают отлично, но только по одному запросу. Составные индексы — это уже целый оркестр, где несколько столбцов играют в идеальной гармонии! Вместе они ускоряют запросы, которые фильтруют или сортируют данные по нескольким полям сразу.

Пример проблемы из реальной жизни:

-- Таблица заказов интернет-магазина
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    user_id INT,
    order_date DATE,
    status VARCHAR(20),
    total_amount DECIMAL(10,2)
);

Если часто ищут заказы конкретного пользователя с определённым статусом — простой индекс по user_id не даст максимальной скорости.


Анатомия составного индекса 🧠

Составной индекс создаётся на два и более столбцов. Порядок столбцов в индексе критически важен — как порядок букв в алфавите!

Создаём супер-индекс:

CREATE INDEX idx_user_status ON orders(user_id, status);

Теперь запрос

SELECT * FROM orders 
WHERE user_id = 42 AND status = 'completed';

будет летать как ракета! 🚀


Волшебные правила порядка столбцов ✨

1️⃣ Принцип левого края: Индекс (A,B,C) работает для запросов с:

  • A
  • A AND B
  • A AND B AND C

Но не для: B AND C или просто C.

2️⃣ Сортируй правильно: Если часто сортируете по total_amount, добавьте его в индекс:

CREATE INDEX idx_user_status_amount ON orders(user_id, status, total_amount);

Теперь этот запрос будет мгновенным:

SELECT * FROM orders
WHERE user_id = 42 AND status = 'completed'
ORDER BY total_amount DESC;

Живые примеры из практики 💼

Кейс 1: Социальная сеть

-- Индекс для быстрого поиска друзей онлайн
CREATE INDEX idx_friends_online ON friendships(user_id, friend_id, is_online)
WHERE is_online = true;

Кейс 2: Логи событий

-- Супер-индекс для аналитики
CREATE INDEX idx_logs_dates ON server_logs(server_id, event_date, event_type);

Когда составные индексы не помогут? ⚠️

1. Если условия в WHERE не используют префикс индекса:

-- Не использует индекс idx_user_status!
SELECT * FROM orders WHERE status = 'completed';

2. При использовании OR вместо AND:

-- Неэффективно, даже с индексом
SELECT * FROM orders 
WHERE user_id = 42 OR status = 'completed';

Эксперимент: замеряем разницу ⏱️

Проведите тест на своей базе:

-- Без индекса
EXPLAIN ANALYZE SELECT * FROM large_table WHERE col1 = 'A' AND col2 = 'B';

-- С индексом
CREATE INDEX idx_col1_col2 ON large_table(col1, col2);
EXPLAIN ANALYZE SELECT * FROM large_table WHERE col1 = 'A' AND col2 = 'B';

Разница в скорости может достигать 1000 раз! Это не магия — это правильно построенные индексы. 🎩✨


Продвинутые фишки для профи 🚀

1. Инклюдированные столбцы (PostgreSQL):

CREATE INDEX idx_cover ON orders(user_id) INCLUDE (status, total_amount);

2. Частичные индексы для горячих данных:

-- Только для активных заказов
CREATE INDEX idx_active_orders ON orders(user_id) 
WHERE status NOT IN ('cancelled', 'completed');

3. Многоколоночная сортировка:

-- Индекс для сложной сортировки
CREATE INDEX idx_sorting_master ON products(category, price DESC, rating DESC);

Как стать повелителем индексов? 🧙‍♂️

  1. Анализируйте частые запросы через EXPLAIN ANALYZE
  2. Начинайте с самых "тяжёлых" запросов
  3. Проверяйте избирательность столбцов (чем уникальнее — тем левее)
  4. Используйте покрывающие индексы для частых SELECT

Помните: каждый новый индекс замедляет INSERT/UPDATE. Баланс — ключ к успешной базе! ⚖️

Скрыть рекламу навсегда

🌱 Индвидидулаьные занятия

Индивидуальные онлайн-занятия по программированию для детей и подростков

Личный подход, без воды, с фокусом на понимание и реальные проекты.

🚀 Записаться на занятие