Отображает план выполнения запроса.
EXPLAIN [ ( option [, ...] ) ] statement
EXPLAIN [ANALYZE] [VERBOSE] statement
Где option может быть одним из следующих:
ANALYZE [ boolean ]
VERBOSE [ boolean ]
COSTS [ boolean ]
BUFFERS [ boolean ]
TIMING [ boolean ]
FORMAT { TEXT | XML | JSON | YAML }
EXPLAIN отображает план запроса, созданный оптимизатором YMatrix или Postgres для указанного оператора. План запроса — это дерево операций для узла. Каждый узел в плане представляет собой отдельную операцию, например сканирование таблицы, соединение, агрегацию или сортировку.
План следует читать снизу вверх, поскольку каждый узел передаёт строки узлу выше. Самый нижний узел плана обычно представляет собой операцию сканирования таблицы (последовательное сканирование, сканирование по индексу или битовой карте индекса). Если запрос требует соединения, агрегации или сортировки (или других операций над исходными строками), то выше узла сканирования будут находиться другие узлы, выполняющие эти операции. Узел верхнего уровня обычно является узлом движения данных в базе данных YMatrix (перераспределение, явное перераспределение, широковещательная рассылка или сбор данных). Эти операции отвечают за перемещение строк между экземплярами сегментов во время обработки запроса.
Вывод команды EXPLAIN содержит одну строку для каждого узла дерева плана, показывающую основной тип узла и следующие оценки стоимости, сделанные планировщиком при выполнении этого узла:
Важно отметить, что стоимость родительского узла включает в себя стоимость всех его дочерних узлов. Верхний узел плана имеет оценку общей стоимости выполнения всего плана — именно это значение оптимизатор стремится минимизировать. При этом стоимость не учитывает время передачи результирующих строк клиенту.
EXPLAIN ANALYZE приводит к фактическому выполнению оператора, а не только к построению плана. Оптимизатор выводит реальные результаты и сравнение с оценками планировщика. Это полезно для проверки того, насколько оценки оптимизатора соответствуют действительности. Помимо информации, отображаемой в обычном плане EXPLAIN, команда EXPLAIN ANALYZE также показывает следующие дополнительные данные:
Work_mem used: 64K bytes avg, 64K bytes max (seg0). Work_mem wanted: 90K bytes avg, 90K bytes max (seg0) to abate workfile I/O affecting 2 workers. [seg0] pass 0: 488 groups made from 488 rows; 263 rows written to workfile [seg0] pass 1: 263 groups made from 263 rowsПримечание: имейте в виду, что при использовании ANALYZE оператор действительно выполняется. Хотя EXPLAIN ANALYZE игнорирует результаты SELECT, другие побочные эффекты оператора происходят в обычном порядке. Если вы хотите использовать EXPLAIN ANALYZE для DML-оператора, не влияя при этом на данные, используйте следующий подход:
BEGIN;
EXPLAIN ANALYZE ...;
ROLLBACK;
Можно указывать только параметры ANALYZE и VERBOSE, причём строго в этом порядке, без заключения списка опций в круглые скобки.
ANALYZE
VERBOSE
COSTS
BUFFERS
TIMING
FORMAT
boolean
statement
Чтобы оптимизатор запросов мог принимать обоснованные решения при оптимизации запросов, следует выполнять команду ANALYZE для сбора статистической информации о распределении данных в таблицах. Если это не сделано (или распределение данных в таблицах значительно изменилось с момента последнего выполнения ANALYZE), оценочная стоимость вряд ли будет соответствовать реальным характеристикам запроса, и, возможно, будет выбран неэффективный план выполнения.
SQL-операторы, выполняемые в рамках команды EXPLAIN ANALYZE, исключаются из очереди ресурсов базы данных YMatrix.
Чтобы проиллюстрировать, как читать план выполнения EXPLAIN, рассмотрим пример очень простого запроса:
EXPLAIN SELECT * FROM names WHERE name = 'Joelle';
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.27 rows=1 width=58)
-> Seq Scan on names (cost=0.00..431.27 rows=1 width=58)
Filter: (name = 'Joelle'::text)
Optimizer: Pivotal Optimizer (GPORCA) version 3.23.0
(4 rows)
Если читать план снизу вверх, оптимизатор начинает с последовательного сканирования таблицы names. Обратите внимание, что условие WHERE используется как фильтр. Это означает, что операция сканирования будет проверять условие для каждой строки и возвращать только те строки, которые ему удовлетворяют.
Результат операции сканирования передаётся в операцию gather motion. В базе данных YMatrix gather motion означает отправку строк сегментов на мастер. В данном случае 3 экземпляра сегментов передают данные одному мастер-экземпляру (3:1). Эта операция выполняется на slice1 параллельного плана выполнения запроса. В YMatrix план запроса разделяется на несколько срезов (slices), чтобы различные части плана могли обрабатываться параллельно этими сегментами.
Оценочная стоимость запуска плана составляет 00.00 (отсутствие затрат), а общая стоимость — 431.27. Оптимизатор оценивает, что данный запрос вернёт одну строку.
Тот же самый запрос, но с подавлением оценки стоимости:
EXPLAIN (COSTS FALSE) SELECT * FROM names WHERE name = 'Joelle';
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Seq Scan on names
Filter: (name = 'Joelle'::text)
Optimizer: Pivotal Optimizer (GPORCA) version 3.23.0
(4 rows)
Тот же запрос с использованием формата JSON:
EXPLAIN (FORMAT JSON) SELECT * FROM names WHERE name = 'Joelle';
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------
[ +
{ +
"Plan": { +
"Node Type": "Gather Motion", +
"Senders": 3, +
"Receivers": 1, +
"Slice": 1, +
"Segments": 3, +
"Gang Type": "primary reader", +
"Startup Cost": 0.00, +
"Total Cost": 431.27, +
"Plan Rows": 1, +
"Plan Width": 58, +
"Plans": [ +
{ +
"Node Type": "Seq Scan", +
"Parent Relationship": "Outer", +
"Slice": 1, +
"Segments": 3, +
"Gang Type": "primary reader", +
"Relation Name": "names", +
"Alias": "names", +
"Startup Cost": 0.00, +
"Total Cost": 431.27, +
"Plan Rows": 1, +
"Plan Width": 58, +
"Filter": "(name = 'Joelle'::text)"+
} +
] +
}, +
"Settings": { +
"Optimizer": "Pivotal Optimizer (GPORCA) version 3.23.0" +
} +
} +
]
(1 row)
Если существует индекс и используется запрос с условием WHERE, допускающим использование индекса, EXPLAIN может показать другой план. Данный запрос использует формат YAML для генерации плана со сканированием по индексу:
EXPLAIN (FORMAT YAML) SELECT * FROM NAMES WHERE LOCATION='Sydney, Australia';
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------
- Plan: +
Node Type: "Gather Motion" +
Senders: 3 +
Receivers: 1 +
Slice: 1 +
Segments: 3 +
Gang Type: "primary reader" +
Startup Cost: 0.00 +
Total Cost: 10.81 +
Plan Rows: 10000 +
Plan Width: 70 +
Plans: +
- Node Type: "Index Scan" +
Parent Relationship: "Outer" +
Slice: 1 +
Segments: 3 +
Gang Type: "primary reader" +
Scan Direction: "Forward" +
Index Name: "names_idx_loc" +
Relation Name: "names" +
Alias: "names" +
Startup Cost: 0.00 +
Total Cost: 7.77 +
Plan Rows: 10000 +
Plan Width: 70 +
Index Cond: "(location = 'Sydney, Australia'::text)"+
Settings: +
Optimizer: "Pivotal Optimizer (GPORCA) version 3.23.0"
(1 row)
В стандарте SQL не определена команда EXPLAIN.