Sobes.tech
Назад к вопросам
Junior — Middle
58

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

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

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

Определение:

Диагностика медленного SQL-запроса — это пошаговый поиск узкого места в запросе, схеме или данных, из-за которого база читает и обрабатывает слишком много строк. Устранение обычно сводится к тому, чтобы сократить объём работы для СУБД: дать ей подходящий индекс, переписать запрос, уменьшить количество возвращаемых данных или исправить устаревшую статистику.

Пример использования:

Допустим, запрос к списку заказов работает медленно:

SELECT o.Id, o.CreatedAt, c.Name
FROM Orders o
JOIN Customers c ON c.Id = o.CustomerId
WHERE o.CreatedAt >= '2025-01-01'
ORDER BY o.CreatedAt DESC;

Если таблица Orders большая, а по CreatedAt и CustomerId нет подходящих индексов, СУБД может читать много строк и долго сортировать результат. В таком случае проверяют план выполнения, затем добавляют индекс по полю фильтрации, а при необходимости — составной индекс под фильтр и join.

Пояснение кода:

  1. Запрос выбирает заказы и имя клиента через JOIN.
  2. Условие WHERE o.CreatedAt >= '2025-01-01' отсекает старые записи.
  3. ORDER BY o.CreatedAt DESC требует сортировки по дате.
  4. Если индекса по CreatedAt нет, база может выполнить полный просмотр таблицы.
  5. Если связь с Customers тоже не оптимальна, время растёт из-за дорогого соединения и лишних чтений.
  6. После добавления подходящего индекса план обычно меняется на более дешёвый: меньше чтений, меньше сортировки, быстрее ответ.

Ключевые моменты:

  • Начинать нужно с EXPLAIN / плана выполнения, а не с хаотичного добавления индексов.
  • Проверять, есть ли full scan, большие сортировки, дорогие JOIN и лишние чтения.
  • Индексы должны соответствовать реальным фильтрам, сортировке и условиям соединения.
  • Избегать функций над колонками в WHERE, если они мешают использованию индекса.
  • Переписывать запрос так, чтобы возвращать только нужные поля и только нужные строки.
  • После изменений обязательно сравнивать не только время, но и количество логических/физических чтений.