Ответ
Неоптимальный запрос можно выявить по нескольким ключевым метрикам и признакам в плане выполнения.
Основные индикаторы проблем:
-
Высокая нагрузка на ресурсы:
- Длительное время выполнения (CPU TIME, ELAPSED TIME).
- Большое количество логических и физических операций чтения (I/O).
-
Неэффективные операции в плане запроса (Execution Plan):
- Table/Index Scan вместо Index Seek. Это указывает на отсутствие подходящего индекса или его неиспользование.
- Key Lookup (RID Lookup) — часто возникает при неполном покрывающем индексе, что приводит к дополнительным операциям поиска.
- Сostly operators: Сортировка (Sort), хэширование (Hash Match) для больших наборов данных, параллелизм (Parallelism) для простых запросов.
- Завышенные оценки числа строк (Estimated vs Actual Rows) — признак устаревшей статистики.
Практический анализ в SQL Server:
-- Включим сбор статистики по времени и I/O
SET STATISTICS TIME ON;
SET STATISTICS IO ON;
-- Выполним проблемный запрос
SELECT o.*, c.Name
FROM dbo.Orders o
JOIN dbo.Customers c ON o.CustomerId = c.Id
WHERE o.Status = 'Pending' AND o.CreatedDate > '2023-01-01';
-- После выполнения смотрим вкладку "Messages" для статистики.
-- Анализируем графический план выполнения (включается Ctrl+M или SET SHOWPLAN_XML ON).
Направления для оптимизации:
- Индексы: Создать недостающие, проверить использование существующих, рассмотреть покрывающие (covering) или columnstore индексы для аналитики.
- Рефакторинг запроса:
- Избегать
SELECT *, явно перечислять нужные столбцы. - Заменять коррелированные подзапросы на
JOINилиAPPLY. - Упрощать условия
WHEREиJOIN.
- Избегать
- Обновление статистики:
UPDATE STATISTICS TableName; - Параметризация: Убедиться, что запросы параметризованы для эффективного повторного использования кэшированного плана.