Индекс — это специальная структура данных, которая ускоряет операции поиска и сортировки в таблицах баз данных. Индексы работают подобно оглавлению в книге, позволяя СУБД быстро находить данные без необходимости полного сканирования таблицы.
Основные типы индексов в SQL Server
1. Кластеризованный индекс
CREATE CLUSTERED INDEX IX_Employees_ID ON Employees(EmployeeID);
- Определяет физический порядок данных в таблице
- Только один на таблицу (поскольку данные могут быть физически упорядочены только одним способом)
- Содержит все данные таблицы в листовых узлах
- Лучше всего подходит для столбцов с уникальными значениями (первичные ключи)
2. Некластеризованный индекс
CREATE NONCLUSTERED INDEX IX_Employees_LastName ON Employees(LastName);
- Отдельная структура от данных таблицы
- Может быть несколько на таблицу (до 999 в SQL Server)
- Содержит ключи индекса + указатель на данные
- Использует кластеризованный индекс (если есть) для поиска данных
3. Уникальный индекс
CREATE UNIQUE INDEX UQ_Employees_Email ON Employees(Email);
- Гарантирует уникальность значений в индексируемых столбцах
- Может быть как кластеризованным, так и некластеризованным
- Автоматически создается для PRIMARY KEY и UNIQUE constraints
4. Составной индекс
CREATE INDEX IX_Employees_DeptName ON Employees(DepartmentID, LastName);
- Создается по нескольким столбцам
- Порядок столбцов критически важен для производительности
- Эффективен для запросов, фильтрующих по префиксу ключа
5. Индекс с включенными столбцами
CREATE INDEX IX_Employees_Covering ON Employees(DepartmentID) INCLUDE (LastName, FirstName);
- Содержит ключевые столбцы + дополнительные включенные столбцы
- Позволяет выполнять запросы без обращения к таблице (index-only scan)
- Уменьшает операции ввода-вывода
Как работают индексы
-
B-дерево — основная структура хранения индексов
- Корневой узел (Root)
- Промежуточные узлы (Intermediate)
- Листовые узлы (Leaf)
-
Статистика — SQL Server использует статистику для оценки эффективности индекса
-
Планировщик запросов решает, использовать ли индекс на основе стоимости операции
Когда использовать индексы
- Столбцы часто используемые в WHERE, JOIN, ORDER BY
- Таблицы с большим количеством строк
- Низкая селективность (высокая уникальность значений)
- Частые поисковые операции против редких изменений данных
Когда индексы могут навредить
- Частые операции INSERT/UPDATE/DELETE
- Маленькие таблицы (полное сканирование может быть быстрее)
- Столбцы с низкой селективностью (например, пол с значениями М/Ж)
- Чрезмерное количество индексов на таблицу
Мониторинг и обслуживание индексов
- Анализ использования:
SELECT * FROM sys.dm_db_index_usage_stats;
- Поиск отсутствующих индексов:
SELECT * FROM sys.dm_db_missing_index_details;
- Перестроение/реорганизация:
ALTER INDEX IX_Employees_ID ON Employees REBUILD;
ALTER INDEX IX_Employees_LastName ON Employees REORGANIZE;
Оптимизация индексов
- Выбирайте правильный тип индекса под задачу
- Следите за порядком столбцов в составных индексах
- Используйте INCLUDE для покрывающих индексов
- Регулярно обслуживайте (дефрагментируйте) индексы
- Удаляйте неиспользуемые индексы
Резюмируем
Индексы — это мощный механизм оптимизации запросов:
- Ускоряют поиск данных (WHERE, JOIN)
- Оптимизируют сортировку (ORDER BY)
- Повышают производительность при правильном использовании
- Требуют баланса между чтением и записью данных
Правильно спроектированные индексы могут улучшить производительность на порядки, но требуют тщательного проектирования и регулярного обслуживания.