План выполнения запроса

План выполнения запроса — подробное описание того, как сервер планирует выполнить пользовательский запрос после компиляции и оптимизаций. План запроса помогает заранее оценить порядок операторов и ожидаемые объёмы данных. План запроса можно получить без фактического выполнения запроса через CLI или UI.

Когда запрос выполняется, план дополнительно обогащается фактической статистикой выполнения и даёт больше данных для анализа.

Обзор режимов

Цель Режим CLI UI Раздел
Оценка плана без выполнения запроса EXPLAIN ydb sql --explain кнопка Explain EXPLAIN через CLI и SDK, EXPLAIN в UI
План с фактическими метриками выполнения EXPLAIN ANALYZE ydb sql --explain-analyze кнопка Run с настройкой Statistics collection mode=Full или кнопка Explain Analyze ANALYZE через CLI, ANALYZE в UI
Графический план в формате SVG SVG ydb sql --explain-analyze --format svg кнопка Run с настройкой Statistics collection mode=Full или кнопка Explain Analyze, затем Open Execution Plan SVG через CLI, SVG в UI

Получение плана выполнения запроса в режиме EXPLAIN через CLI и SDK

Рассмотрим простой запрос:

SELECT n_name
  FROM nation
  JOIN region ON nation.n_regionkey == region.r_regionkey
  WHERE r_name = "AMERICA"

Чтобы узнать план этого запроса, не выполняя его, необходимо выполнить команду ydb sql с указанием параметра --explain (предполагается, что текст запроса находится в файле file1.sql):

ydb sql -f file1.sql --explain

В терминале будет выведено следующее:

┌────────┬────────┬────────┬────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ E-Cost │ E-Rows │ E-Size │ Operation                                                                                          │
├────────┼────────┼────────┼────────────────────────────────────────────────────────────────────────────────────────────────────┤
│        │        │        │ ┌> ResultSet                                                                                       │
│ 2003   │ 3      │ 457    │ └─┬> InnerJoin (Map) (nation.n_regionkey = region.r_regionkey)                                     │
│ 0      │ 25     │ 1212   │   ├──> TableFullScan (Table: nation, ReadColumns: ["n_nationkey (-∞, +∞)","n_name","n_regionkey"]) │
│ 0      │ 1      │ 67     │   └─┬> Filter (Blocks: True, r_name == "AMERICA", Pushdown: True)                                  │
│ 0      │ 5      │ 672    │     └──> TableFullScan (Table: region, ReadColumns: ["r_regionkey (-∞, +∞)","r_name"])             │
└────────┴────────┴────────┴────────────────────────────────────────────────────────────────────────────────────────────────────┘

В колонке Operation показана структура запроса в виде дерева операторов. Здесь видно, что сервер планирует следующую последовательность выполнения (снизу вверх):

  • прочитать таблицу region
  • применить предикат (фильтр) к полю r_name со значением AMERICA
  • соединить результат с содержимым таблицы nation

В других колонках — прогнозные (estimated, отсюда E-Cost, E-Rows и т.п.) оценки оптимизатора:

Колонка Назначение
E-Cost Оценка стоимости фрагмента плана
E-Rows Ожидаемое число строк
E-Size Ожидаемый объём данных

Оценки стоимостной оптимизатор выводит из статистики источников данных и структуры запроса.

В примере выше показан человекочитаемый табличный вывод. Тот же план в JSON можно получить, вызывая запрос с параметром --format json-unicode (или при вызове через SDK). Пример:

ydb sql -f file1.sql --explain --format json-unicode

Вывод достаточно объёмный и здесь приведён лишь частично:

{
    "Plan" : {
        "Plans" : [
            {
                "PlanNodeId" : 6,
                "Plans" : [
                    {
"..."
                    }
                ],
                "Node Type" : "ResultSet",
                "PlanNodeType" : "ResultSet"
            }
        ],
        "Node Type" : "Query",
        "PlanNodeType" : "Query"
    }
}

Получение плана выполнения запроса в режиме EXPLAIN в UI

В графическом интерфейсе YDB также можно получить план выполнения, для этого надо использовать кнопку [Explain]. В UI доступно больше вариантов плана. По умолчанию показывается закладка Computation Graph, граф вычислений в виде операторов и связей между ними:

Граф выполнения в UI

Если переключиться на вкладку Explain, вы увидите план, похожий на вывод CLI:

Получение EXPLAIN плана в UI

Оставшиеся вкладки позволяют также исследовать исходную структуру плана в формате JSON на одноимённой вкладке, а также ознакомиться с низкоуровневым форматом, в который компилируется программа на вкладке AST.

Получение фактического плана выполнения запроса через CLI

Чтобы получить фактический план выполнения запроса, следует запустить команду ydb sql с опцией --explain-analyze. Вывод в терминале при этом несколько изменится — в дополнение к оценкам оптимизатора появятся актуальные (actual, отсюда A-CPU, A-Rows) метрики, собранные во время работы запроса:

┌───────┬────────┬────────┬────────┬────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ A-Cpu │ A-Rows │ E-Cost │ E-Rows │ E-Size │ Operation                                                                                                       │
├───────┼────────┼────────┼────────┼────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│       │        │        │        │        │ ┌> ResultSet                                                                                                    │
│ 1     │ 5      │ 2003   │ 3      │ 457    │ └─┬> InnerJoin (Map) (A-SelfCpu: 0.367, nation.n_regionkey = region.r_regionkey, A-Size: 54)                    │
│       │ 25     │ 0      │ 25     │ 1212   │   ├──> TableFullScan (Table: nation, ReadColumns: ["n_nationkey (-∞, +∞)","n_name","n_regionkey"], A-Size: 577) │
│ 0     │ 1      │ 0      │ 1      │ 67     │   └─┬> Filter (r_name == "AMERICA", A-SelfCpu: 0.333, Blocks: True, Pushdown: True, A-Size: 16)                 │
│       │ 1      │ 0      │ 5      │ 672    │     └──> TableFullScan (Table: region, ReadColumns: ["r_regionkey (-∞, +∞)","r_name"], A-Size: 13)              │
└───────┴────────┴────────┴────────┴────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Получение фактического плана выполнения запроса в UI

Аналогично, фактический план выполнения запроса доступен в UI при обычном выполнении кнопкой [Run] с включенными настройками Statistics collection mode = Full или при нажатии на кнопку [Explain Analyze]. Как и в случае с CLI, добавляются актуальные метрики — вывод похож на рисунок в разделе Получение EXPLAIN плана в UI.

Получение графического плана запроса через CLI

Фактический план выполнения запроса в формате SVG можно получить посредством утилиты командной строки. Для этого надо изменить формат вывода плана, добавив опцию --format svg:

ydb sql -f file1.sql --explain-analyze --format svg > plan1.svg

Формат SVG сам по себе текстовый, но предназначен для отображения специальными средствами просмотра, поэтому обычно имеет смысл сохранить полученный план в файл, как в показанном примере, а потом открыть его, например, в браузере.

Опция --format svg может быть использована и вместе с опцией --explain тоже. Так как в этом случае запрос реально не выполняется, то никакой статистики не будет, поэтому в плане будет показана только часть, связанная со структурой запроса.

Получение графического плана запроса в UI

Чтобы в YDB UI отображался графический план запроса, включите настройку Experiments | Execution plan.

Примечание

Графический план запроса в UI пока относится к экспериментальным возможностям (раздел Experiments). Со временем он должен перейти в обычные настройки интерфейса.

Включение графического представления в UI

После этого выполните запрос, например:

SELECT count(*) FROM lineitem

В дополнительном меню справа (кнопка [...], отображается на всех вкладках интерфейса) появятся пункты:

  • Open Execution Plan — открыть фактический план запроса в новой вкладке браузера;
  • Download Execution Plan — сохранить фактический план запроса в файл.

Там же есть пункт Download Diagnostics.

Просмотр и сохранение плана

Для этого запроса он будет выглядеть примерно так (конкретные значения метрик зависят от конфигурации и нагрузки кластера):

План выполнения запроса

Об элементах диаграммы подробнее — в разделе «Графический план запроса»: Расположение информации в плане запроса, Структура фактического плана запроса и Визуализация метрик запроса.