Commands
Trino

EXPLAIN ANALYZE: Анализ плана запроса с реальной статистикой выполнения

Анализ плана запроса с реальной статистикой выполнения

Вот шпаргалка по EXPLAIN ANALYZE в Trino. Использую эту команду постоянно для отладки тяжёлых запросов.

Базовый синтаксис

Просто добавь EXPLAIN ANALYZE перед своим запросом. Trino выполнит его и вернёт план с реальной статистикой: сколько строк обработал каждый узел, сколько времени заняло, сколько данных прочитал.

EXPLAIN ANALYZE
SELECT count(*) FROM events WHERE event_date = current_date;

Вывод разделён на две части:

  1. План выполнения (Query Plan): Иерархия операций (сканирование, фильтрация, агрегация).
  2. Статистика (Execution Statistics): Для каждого шага показаны фактические rows, CPU time, Input rows, Input size. Ключевое — здесь не оценки, а цифры после реального выполнения.

Полезные флаги

Флаг VERBOSE — основной. Он раскладывает каждый этап плана на подробные метрики, включая распределение по задачам (tasks). Без него статистика агрегированная.

Когда это нужно? Когда видишь в плане ScanFilterProject и непонятно, что именно съело время: чтение данных или их фильтрация. С VERBOSE станет ясно.

EXPLAIN ANALYZE (VERBOSE)
SELECT user_id, sum(amount)
FROM transactions
WHERE status = 'failed'
  AND transaction_date > date '2024-01-01'
GROUP BY 1;

В выводе смотри на операторы ScanFilterProject и FilterProject. В них появится детализация:

  • Input avg. per task: средний объём данных на каждую задачу.
  • CPU time per task: время CPU на задачу.
  • Input rows per task: строк на задачу. Это сразу показывает равномерность распределения нагрузки (skew).

Типичные сценарии

Сценарий 1: Определение узкого места в JOIN. Запрос выполняется минуту. Запускаешь EXPLAIN ANALYZE и видишь, что этап LookupJoin занял 55 секунд, обработав миллиард строк. Становится очевидно, что проблема не в чтении данных, а в неоптимальном соединении. Решение — проверить наличие нужных ключей в JOIN или переписать запрос.

Сценарий 2: Анализ эффективности фильтрации в распределённой таблице. После VERBOSE в статистике ScanFilterProject видишь: Input rows per task: 1.2M, но Output rows per task: 100. Это значит, что на каждую задачу пришлось отфильтровать 1.2 миллиона строк, чтобы получить 100 полезных. Вывод: предикат (условие WHERE) слабо сокращает данные, возможно, нужен партиционирование или другой индекс.

Частые ошибки

  1. Запуск на продакшене без LIMIT. EXPLAIN ANALYZE выполняет запрос полностью. Если забыть поставить LIMIT на тестовый запрос к огромной таблице, можно нечаянно запустить полный тяжёлый расчёт и нагрузить кластер.

  2. Неправильная интерпретация времени. В плане есть CPU time и Wall time. Wall time (реальное время) может быть меньше суммы CPU time на узлах, потому что операции выполняются параллельно. Смотри на Wall time как на общую длительность этапа, а на высокий CPU time — как на показатель высокой вычислительной стоимости.