EXPLAIN¶
Для анализа производительности запросов в Picodata можно использовать команду
EXPLAIN, с помощью которой можно узнать, как будет выглядеть план исполнения
запроса. План позволяет наглядно оценить структуру и последовательность действий
при выполнении запроса.
В реализацию EXPLAIN заложены следующие принципы:
- Фасеты (режимы отображения)
- Достоверность плана
- Возможность применения к проблемным запросам
- Возможности форматирования
Синтаксис¶
Фасеты (режимы отображения)¶
Команда EXPLAIN позволяет указывать определенные режимы вывода EXPLAIN,
также называемые фасетами. В настоящий момент можно указывать фасеты RAW,
LOGICAL, BUCKETS, FORWARD и CONTEXT в любом порядке. Каждый фасет
отвечает за конкретную информацию о запросе.
При указании нескольких фасетов одновременно также печатаются их заголовки, позволяющие быстро ориентироваться в выводе. Например:
EXPLAIN (LOGICAL, BUCKETS) SELECT name, id FROM _pico_table;
──────────────────────────────────────────────────────────────────────
# Logical plan
──────────────────────────────────────────────────────────────────────
projection (_pico_table.name::string -> name, _pico_table.id::int -> id)
scan _pico_table
──────────────────────────────────────────────────────────────────────
# Buckets
──────────────────────────────────────────────────────────────────────
buckets = any
Если для EXPLAIN не указано ни одного фасета, то фасетами по умолчанию являются
LOGICAL и BUCKETS. Таким образом, запросы
EXPLAIN (LOGICAL, BUCKETS) SELECT name, id FROM _pico_table;
и
EXPLAIN SELECT name, id FROM _pico_table;
эквивалентны.
С подробным описанием каждого фасета EXPLAIN можно ознакомиться тут:
- RAW — низкоуровневый план исполнения запроса.
- LOGICAL — высокоуровневый план исполнения запроса.
- BUCKETS — информация о бакетах, участвующих в исполнении запроса.
- FORWARD — анализ сетевых пересылок, необходимых для исполнения запроса.
- CONTEXT — прочие переменные среды, влияющие на исполнение запроса.
Достоверность плана¶
Команда EXPLAIN в Picodata показывает полный план запроса — со всеми операциями,
которые реально выполняются, даже если они не следуют напрямую из текста
запроса. Например, COUNT(*) в Picodata исполняется путем частичного подсчёта
на узлах хранения и финального суммирования результатов. Это следует из вывода
фасета LOGICAL:
EXPLAIN (LOGICAL) SELECT COUNT(*) FROM t;
projection (sum(count_1::int)::int -> col_1)
motion [policy: full, program: ReshardIfNeeded]
projection (count(*)::int -> count_1)
scan t
Узел motion отражает перераспределение данных между узлами кластера. Подробнее
об этом можно почитать здесь.
Возможность применения к проблемным запросам¶
Важной особенностью EXPLAIN в Picodata является возможность получить EXPLAIN для
запросов, которые приводят к ошибке при исполнении. Так, Picodata всегда
старается построить EXPLAIN для синтаксически корректных запросов, даже если они
семантически некорректные. Например:
SELECT name, id FROM _pico_table WHERE MAX(id) = 5;
ERROR: sbroad: Query 1 from EXPLAIN (RAW): Failed to compile SQL statement: misuse of aggregate function MAX()
Тем не менее, Picodata выполнит EXPLAIN от такого запроса:
EXPLAIN (RAW) SELECT name, id FROM _pico_table WHERE MAX(id) = 5;
╭───────────────────╮
│ 1. Query (ROUTER) │
╰───────────────────╯
SELECT "_pico_table"."name", "_pico_table"."id" FROM "_pico_table" WHERE max (CAST ("_pico_table"."id" as int)) = CAST(5 AS int)
plan:
Failed to compile SQL statement: misuse of aggregate function MAX()
На данный момент у возможности построить EXPLAIN для проблемных запросов есть
ограничения:
- Нельзя получить
EXPLAINдля запроса с транзакционным блоком, если он затрагивает более одного бакета.
Возможности форматирования¶
В Picodata для EXPLAIN также существует опция FMT, которая применяется к
фасетам. В случае LOGICAL форматирование применяется к плану. В случае RAW
форматирование применяется к локальным SQL-запросам и их планам. Ниже приведены
примеры.
Пример с LOGICAL:
EXPLAIN (LOGICAL) SELECT id, item FROM warehouse;
projection (warehouse.id::int -> id, warehouse.item::string -> item)
scan warehouse
При указании опции FMT вывод форматируется:
EXPLAIN (LOGICAL, FMT) SELECT id, item FROM warehouse;
projection (
warehouse.id::int -> id,
warehouse.item::string -> item
)
scan warehouse
Пример с RAW:
EXPLAIN (RAW) SELECT * FROM warehouse;
╭──────────────────────────╮
│ 1. Query (WHOLE STORAGE) │
╰──────────────────────────╯
SELECT "warehouse"."id", "warehouse"."item", "warehouse"."type" FROM "warehouse"
plan:
[0] SCAN TABLE warehouse (~1048576 rows)
При указании опции FMT вывод будет отформатирован:
EXPLAIN (RAW, FMT) SELECT * FROM warehouse;
╭──────────────────────────╮
│ 1. Query (WHOLE STORAGE) │
╰──────────────────────────╯
SELECT
"warehouse"."id",
"warehouse"."item",
"warehouse"."type"
FROM
"warehouse"
plan:
[0] SCAN TABLE warehouse (~1048576 rows)
Опцию FMT полезно использовать при анализе вывода EXPLAIN для сложных запросов.
В будущем могут быть добавлены как новые фасеты, так и новые способы
форматирования их элементов.