EXPLAIN ANALYZE: Анализ плана запроса с реальной статистикой выполнения
Анализ плана запроса с реальной статистикой выполнения
Вот шпаргалка по EXPLAIN ANALYZE в Trino. Использую эту команду постоянно для отладки тяжёлых запросов.
Базовый синтаксис
Просто добавь EXPLAIN ANALYZE перед своим запросом. Trino выполнит его и вернёт план с реальной статистикой: сколько строк обработал каждый узел, сколько времени заняло, сколько данных прочитал.
EXPLAIN ANALYZE
SELECT count(*) FROM events WHERE event_date = current_date;
Вывод разделён на две части:
- План выполнения (Query Plan): Иерархия операций (сканирование, фильтрация, агрегация).
- Статистика (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) слабо сокращает данные, возможно, нужен партиционирование или другой индекс.
Частые ошибки
-
Запуск на продакшене без LIMIT.
EXPLAIN ANALYZEвыполняет запрос полностью. Если забыть поставитьLIMITна тестовый запрос к огромной таблице, можно нечаянно запустить полный тяжёлый расчёт и нагрузить кластер. -
Неправильная интерпретация времени. В плане есть
CPU timeиWall time.Wall time(реальное время) может быть меньше суммыCPU timeна узлах, потому что операции выполняются параллельно. Смотри наWall timeкак на общую длительность этапа, а на высокийCPU time— как на показатель высокой вычислительной стоимости.