Как разбирать медленный SQL-запрос по плану выполнения

Разбор селективности, соединений и сортировок с безопасным сравнением плана до и после изменения.

Практическое решение · 4 мин чтения
Как разбирать медленный SQL-запрос по плану выполнения — tarasovcode
Базы данныхКак разбирать медленный SQL-запрос по плану выполнения

Отчет по заказам быстро работал на небольшой таблице, но замедлился после роста истории. Переписывание SQL на глаз часто меняет смысл выборки или помогает только отдельному параметру. Разбор начинается с ожидаемого результата и оценки того, сколько строк проходит через каждый узел плана.

Что подготовить

  • SQL с параметрами и описание ожидаемых строк, включая правила обработки пустых значений.
  • Схема таблиц, существующие индексы, приблизительные размеры и распределение значений в фильтрах.
  • План выполнения и доступная статистика фактических строк; выполнение тяжелого запроса проводите на безопасной копии.

Порядок работы

  1. Сохраните эталонный результат на небольшом наборе с дубликатами, пустыми значениями и заказами без связанных записей.
  2. Прочитайте план снизу вверх: найдите чтение большого объема, рост строк после соединения и дорогую сортировку.
  3. Сравните оценку количества строк с фактическим значением. Сильное расхождение может объясняться статистикой или зависимостью между колонками.
  4. Проверьте, соответствует ли предполагаемый индекс условиям фильтрации и порядку сортировки. Учтите цену индекса для записи и хранения.
  5. Измените один элемент: условие, порядок подготовки данных или индекс. Сравните время и объем чтения для нескольких характерных параметров.

Разобранный пример

Допустим, отчет фильтрует заказы по организации и месяцу, затем соединяет позиции. Из миллиона заказов подходит тысяча, но соединение выполняется до ограничения диапазона. Проверяемая гипотеза: ранний отбор заказов уменьшит промежуточный набор. Подтверждение — меньше строк в узле соединения при том же итоге отчета.

Как проверить результат

  • Количество строк и содержимое совпадают с эталоном, включая поведение внешних соединений.
  • Проверены частый и редкий фильтр, пустая выборка и большой диапазон дат.
  • Улучшение не зависит исключительно от повторного чтения уже прогретых страниц.

Если что-то пошло не так

Если новый индекс не используется, не принуждайте планировщик немедленно. Проверьте приведение типов, функции над колонкой и долю подходящих строк. При ухудшении записи оцените полный жизненный цикл индекса и удалите экспериментальный объект в согласованном порядке.

Промпт для разбора ваших материалов

Изучи SQL, схему и приложенный план. Для каждого дорогого узла объясни объем данных и возможную причину. Предложи минимальные изменения, перечисли риски изменения результата и подготовь сравнительные проверки. Не утверждай, что индекс ускорит запрос, без плана проверки.

Частые вопросы

Всегда ли полное сканирование плохо?

Нет. Когда нужна значительная часть таблицы, последовательное чтение может быть разумнее многочисленных обращений через индекс.

Можно ли сравнить только время?

Добавьте количество прочитанных строк, обращений к данным и размер результата. Иначе влияние кеша легко принять за улучшение запроса.

Материал библиотеки решений Ильи Тарасова / TarasovWeb.

Карточка разбора узла плана

Для подозрительного участка выпишите тип операции, оценку выходных строк, фактическое число строк, число повторений и связь с родительским узлом. Не складывайте времена вложенных узлов механически: часть работы уже учтена выше. Сначала выясните, является ли значение показателем одного выполнения или результатом повторных проходов. Конкретный формат зависит от используемой СУБД.

Полезный учебный случай — соединение заказов и позиций. До соединения отобраны нужные заказы, но один заказ содержит много позиций. Рост количества строк после соединения может быть корректным. Ошибка начинается, когда следующий расчёт считает строки за количество заказов. Поэтому вместе с ускорением проверяйте бизнес-смысл итогов: уникальные заказы, суммы и обработку заказов без позиций.

Разделите эксперименты на изменение запроса и изменение структуры хранения. Для индекса заранее запишите, какой фильтр или порядок он должен поддерживать. Для переписывания соединения подготовьте маленький набор с известным ответом. Если план изменился, но итоговые строки стали другими, эксперимент нельзя считать успешным независимо от скорости.

В PostgreSQL команда EXPLAIN ANALYZE исполняет запрос, поэтому её применение к изменяющим операциям требует осознанного выбора безопасной среды. Формат и смысл показателей уточняйте в официальном руководстве по EXPLAIN. Сохраните план до изменения: он понадобится, если новые параметры данных вернут прежнюю задержку.

О проекте

Практическая библиотека Ильи Тарасова и TarasovWeb. Telegram-канал · Личная страница · ВКонтакте.

#tarasovweb #ИльяТарасов