← Назад к вопросам

По какому правилу понимаешь сколько индексов нужно делать в SQL?

2.2 Middle🔥 201 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Критерии проектирования индексов в SQL

Проектирование индексов — это баланс между производительностью чтения и стоимостью записи. Я придерживаюсь следующих правил и принципов:

1. Анализ запросов и workload

Перед созданием любого индекса необходимо проанализировать:

  • Частоту выполнения запросов (OLTP vs OLAP)
  • Типы операций: SELECT, JOIN, WHERE, ORDER BY, GROUP BY
  • Кардинальность столбцов (уникальность значений)
  • Изменчивость данных (частота INSERT/UPDATE/DELETE)
-- Пример: индекс для частых поисков по email
CREATE INDEX idx_users_email ON Users(Email);

-- Составной индекс для запросов с WHERE и ORDER BY
CREATE INDEX idx_orders_user_status_date ON Orders(UserId, Status, OrderDate DESC);

2. Принцип избирательности (Selectivity)

Высокоселективные столбцы (с высокой уникальностью) должны быть первыми в индексе:

  • Столбцы с 95%+ уникальных значений — лучшие кандидаты для индексации
  • Булевские поля или низкокардинальные столбцы (пол, статус) обычно не индексируют отдельно, только в составе составных индексов

3. Правило покрывающих индексов (Covering Index)

Индекс должен полностью удовлетворять запрос без обращения к таблице:

-- Плохо: нужен lookup в таблицу
SELECT FirstName, LastName FROM Users WHERE Email = 'test@mail.ru';

-- Хорошо: covering индекс
CREATE INDEX idx_users_email_covering ON Users(Email) INCLUDE (FirstName, LastName);

4. Составные индексы и порядок столбцов

Порядок столбцов в составном индексе критически важен:

  1. Равенство (WHERE col = value) → первыми
  2. Диапазоны (BETWEEN, >, <) → после равенств
  3. Сортировка (ORDER BY) → последними
-- Оптимальный порядок для запроса:
-- WHERE DepartmentId = 5 AND Salary > 50000 ORDER BY HireDate
CREATE INDEX idx_emp_dept_salary_date ON Employees(DepartmentId, Salary, HireDate);

5. Ограничение количества индексов

Рекомендации для OLTP-систем:

  • Не более 5-7 индексов на таблицу (каждый индекс замедляет INSERT/UPDATE на 5-10%)
  • Мониторинг использования индексов через системные представления:
SELECT * FROM sys.dm_db_index_usage_stats;
SELECT * FROM sys.dm_db_missing_index_details;

6. Специфические типы индексов

  • Кластеризованный индекстолько один на таблицу, определяет физический порядок данных
  • Некластеризованные индексы — для остальных сценариев
  • Filtered индексы — для подмножества данных:
CREATE INDEX idx_active_users ON Users(Email) WHERE IsActive = 1;

7. Антипаттерны и предостережения

  • Индексы по всем столбцам — "индексный взрыв" снижает производительность записи
  • Дублирующие индексы(A,B) и (A) — второй избыточен
  • Индексы на часто изменяемые столбцы — ведут к фрагментации
  • Игнорирование статистики — устаревшая статистика делает индексы бесполезными

Практический алгоритм принятия решений

  1. Профилирование — выявить 20% самых дорогих запросов
  2. Анализ планов выполнения — найти missing indexes, сканирования вместо поиска
  3. Создание приоритетных индексов — начинать с covering индексов для критичных запросов
  4. Тестирование — проверять влияние на SELECT/INSERT под нагрузкой
  5. Мониторинг — регулярно пересматривать набор индексов

Итоговое правило: каждый индекс должен решать конкретную проблему производительности, подтвержденную метриками. "Индексировать на всякий случай" — прямой путь к деградации производительности в production-среде. Современные СУБД предоставляют богатые инструменты для анализа (Execution Plans, Query Store, Extended Events), которые должны стать основой для принятия решений об индексации.