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

«По каким признакам определяют необходимость создания индекса в реляционной базе данных?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Необходимость создания индекса определяется анализом запросов и их производительности. Индекс — это компромисс между скоростью чтения и затратами на запись/хранение.

Ключевые критерии для добавления индекса:

  1. Частые операции поиска (WHERE), соединения (JOIN) или сортировки (ORDER BY, GROUP BY) по определенному столбцу или набору столбцов.
  2. Низкая производительность SELECT-запросов, что подтверждается планами выполнения (EXPLAIN / EXPLAIN ANALYZE), показывающими полное сканирование таблицы (Sequential Scan, Full Table Scan).
  3. Высокая кардинальность столбца (много уникальных значений). Индексы для полей с низкой кардинальностью (например, пол, статус_заказа) часто неэффективны.
  4. Обеспечение ограничений целостности: PRIMARY KEY и UNIQUE constraints автоматически создают индексы.
  5. Большой объем данных в таблице (тысячи и более строк), где поиск без индекса становится дорогим.

Когда индекс может быть вреден (или не нужен):

  • Частые операции записи (INSERT, UPDATE, DELETE): Каждая модификация данных требует обновления индекса, что замедляет эти операции.
  • Маленькие таблицы, которые помещаются в память за одно обращение.
  • Столбцы, которые никогда не используются в условиях отбора или соединения.

Практический пример:

-- Медленный запрос до создания индекса
SELECT * FROM orders WHERE user_id = 1234 AND status = 'PROCESSING';

-- Анализ плана запроса (в PostgreSQL)
EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 1234 AND status = 'PROCESSING';
-- В выводе может быть: "Seq Scan on orders ..."

-- Создание составного индекса для ускорения этого запроса
CREATE INDEX idx_orders_user_status ON orders(user_id, status);

-- После создания индекса план запроса должен измениться на "Index Scan using idx_orders_user_status..."

Важно: Создание индексов должно быть обоснованным. Следует мониторить производительность как запросов на чтение, так и на запись после их добавления.