Вопросы по теме «EXPLAIN и оптимизация»

EXPLAIN показывает план выполнения запроса и помогает понять, где теряется производительность. На собеседованиях спрашивают про индексы, Seq Scan vs Index Scan, стоимость JOIN-ов и как переписать медленный запрос. Этот навык отличает аналитика, который просто пишет SQL, от того, кто понимает, как база данных его выполняет.

Всего в этом разделе 20 вопросов. Каждый — с правильным ответом и кратким разбором теории. Разбито на 4 части по 5 вопросов.

Агрегация, GROUP BY и HAVINGДаты и времяВыражения и NULLJOIN и операции множествОсновы SQL-запросовСтроки и приведение типовПодзапросы и CTEОконные функции

Вопросы 15 из 20

1Чем `EXPLAIN` отличается от `EXPLAIN ANALYZE` в Postgres-подобной СУБД?
A`EXPLAIN` выполняет запрос и показывает фактическое время, а `EXPLAIN ANALYZE` — только план без выполнения.
B`EXPLAIN` показывает план без выполнения запроса, а `EXPLAIN ANALYZE` выполняет запрос и добавляет фактические времена/строки.
CОба варианта всегда только строят план и ничего не исполняют.
DОба варианта всегда исполняют запрос, разницы нет.
Ответ: `EXPLAIN` — план, `EXPLAIN ANALYZE` — план плюс фактические измерения.

Обычный `EXPLAIN` полезен, когда вы хотите оценить риск и структуру плана, не запуская потенциально тяжёлый запрос. `EXPLAIN ANALYZE` действительно выполняет запрос и показывает фактические времена и количество строк на шагах. Это помогает обнаружить расхождения между оценками и реальностью, но может быть дорого на больших таблицах.

2Как удобнее интерпретировать дерево `EXPLAIN`, чтобы понять, откуда берутся строки и где тратятся ресурсы?
AСверху вниз: сначала выполняется верхний узел, затем нижние.
BСнизу вверх: сначала выполняются узлы сканирования/фильтрации, а затем их результаты поднимаются к верхним узлам.
CСлева направо: порядок зависит от ширины вывода.
DВ любом направлении, потому что `EXPLAIN` показывает шаги в случайном порядке.
Ответ: Чаще всего план читают снизу вверх: сканы → обработка → результат.

В плане нижние узлы производят данные (например, `Seq Scan` или `Index Scan`). Дальше эти потоки обрабатываются: применяются условия, агрегации (`Aggregate`), сортировки (`Sort`) и в конце обрезка (`Limit`). Такой подход помогает связать узкие места с источником большого объёма строк.

3Вы хотите добавить новый запрос в дашборд и боитесь, что он сильно нагрузит базу, потому что таблица `events` очень большая. Что дает запуск `EXPLAIN` для этого запроса?
AОн выполнит запрос и вернет точное время выполнения в миллисекундах.
BОн покажет предполагаемый план выполнения (например, `Seq Scan` или `Index Scan`) без выполнения запроса.
CОн автоматически создаст нужные индексы для ускорения.
DОн заблокирует таблицу, чтобы результат был стабильным.
Ответ: `EXPLAIN` показывает план выполнения и помогает оценить риск тяжёлого запроса без его запуска.

В Postgres-подобных СУБД `EXPLAIN` отображает выбранные шаги плана (например, `Seq Scan`, `Index Scan`, `Sort`, операции для `JOIN`) и их оценки. Это полезно, чтобы увидеть потенциальные узкие места до запуска запроса в проде. В отличие от `EXPLAIN ANALYZE`, обычный `EXPLAIN` не выполняет запрос.

4Вы считаете число заказов по таблице `orders`, но добавили `JOIN` к таблице `order_items` и получили подозрительно большой результат. В `EXPLAIN` оценка `rows` после соединения стала намного больше, чем `rows` на входе. Что это чаще всего означает?
A`EXPLAIN` сообщает точное время выполнения, и оно будет «намного больше».
BСоединение `JOIN` умножает строки (связь один-ко-многим), и агрегат вроде `COUNT(*)` может считать позиции, а не заказы; нужно проверить логику (`COUNT(DISTINCT orders.id)` или агрегация до `JOIN`).
CИндекс обязательно отсутствует и без него корректность невозможна.
DЭто признак того, что база «потеряла» первичный ключ.
Ответ: План помогает заметить «размножение» строк из‑за `JOIN` и связать это с корректностью метрики.

Если после `JOIN` ожидаемое количество строк резко растёт, это часто нормальное следствие отношения один-ко-многим. Но для аналитики важно, что агрегат может начать считать не то (например, позиции вместо заказов). `EXPLAIN` не докажет корректность сам по себе, но он подскажет, где возникает кратность и где стоит пересмотреть агрегацию.

5В `EXPLAIN` вы видите оценку `rows=10`, но по смыслу запроса ожидаете тысячи строк. Какое объяснение и следующий шаг наиболее разумны?
AЭто может быть ошибка оценок (статистика/распределение данных), из‑за чего план может быть неоптимальным; стоит проверить реальную кардинальность (например, через `EXPLAIN ANALYZE`) и при необходимости обновить статистику (`ANALYZE`) или уточнить фильтр.
BСкорее всего, статистика корректна, а оценка `rows=10` означает, что индекс слишком селективен; нужно добавить составной индекс на колонки фильтра и перезапустить запрос без изменений.
CВероятно, `JOIN` отфильтровал лишние строки из-за несовпадения типов; следует привести типы ключей JOIN к одному типу и затем проверить план через `EXPLAIN` повторно.
DСкорее всего, `rows` отражает количество строк после применения `LIMIT`; нужно убрать `LIMIT` из запроса, чтобы планировщик показал реальный объём данных.
Ответ: Сильные расхождения в `rows` — повод подозревать неверные оценки и возможный плохой план.

`rows` в `EXPLAIN` — это прогноз планировщика. Если он сильно не совпадает с реальностью, оптимизатор может выбрать неправильный тип скана или порядок соединений. Для аналитика полезно: (1) подтвердить факт через `EXPLAIN ANALYZE` на безопасном окружении и (2) договориться об обновлении статистики (`ANALYZE`) или переписать условия так, чтобы оценки стали точнее.

1234

Хотите тренировать интерактивно?

В приложении — таймер, прогресс, стрики и 1700+ вопросов по всем темам.

Тренировать в Telegram

Другие темы: SQL

Агрегация, GROUP BY и HAVINGДаты и времяВыражения и NULLJOIN и операции множествОсновы SQL-запросовСтроки и приведение типовПодзапросы и CTEОконные функции