EXPLAIN#
EXPLAIN
EXPLAIN — показать план выполнения оператора
Синтаксис
EXPLAIN [ (option
[, ...] ) ]statement
EXPLAIN [ ANALYZE ] [ VERBOSE ]statement
whereoption
can be one of: ANALYZE [boolean
] VERBOSE [boolean
] COSTS [boolean
] SETTINGS [boolean
] BUFFERS [boolean
] WAL [boolean
] TIMING [boolean
] SUMMARY [boolean
] FORMAT { TEXT | XML | JSON | YAML }
Описание
Эта команда отображает план выполнения, который генерирует планировщик Tantor SE для предоставленного оператора. План выполнения показывает, как таблицы, на которые ссылается оператор, будут сканироваться - путем простого последовательного сканирования, индексного сканирования и т. д. - и если идет ссылка на несколько таблиц, какие алгоритмы соединения будут использоваться для соединения необходимых строк из каждой входной таблицы.
Самая важная часть отображения - это предполагаемая стоимость выполнения оператора, которая является предположением планировщика о том, сколько времени потребуется для выполнения оператора (измеряется в единицах стоимости, которые произвольны, но обычно означают загрузку страниц диска). Фактически, показываются два числа: стоимость запуска до того, как может быть возвращена первая строка, и общая стоимость для возврата всех строк. Для большинства запросов важна общая стоимость, но в контекстах, таких как подзапрос в EXISTS
, планировщик выберет наименьшую стоимость запуска вместо наименьшей общей стоимости (поскольку исполнитель все равно остановится после получения одной строки). Кроме того, если вы ограничиваете количество возвращаемых строк с помощью предложения LIMIT
,планировщик делает соответствующую интерполяцию между конечными стоимостями, чтобы оценить, какой план на самом деле является самым дешевым.
Опция ANALYZE
вызывает фактическое выполнение оператора, а не только его планирование. Затем к отображению добавляются фактические статистические данные о времени выполнения, включая общее затраченное время в каждом узле плана (в миллисекундах) и общее количество строк, которые он фактически вернул. Это полезно для определения, насколько оценки планировщика близки к реальности.
Важно
Имейте в виду, что оператор фактически выполняется, когда
используется опция ANALYZE
. Хотя
EXPLAIN
отбросит любой вывод, который бы
SELECT
вернул, другие побочные эффекты от
оператора произойдут как обычно. Если нужно использовать
EXPLAIN ANALYZE
на
INSERT
, UPDATE
,
DELETE
, MERGE
,
CREATE TABLE AS
,
или EXECUTE
операторе
без воздействия на ваши данные, используйте этот подход:
BEGIN; EXPLAIN ANALYZE ...; ROLLBACK;
Только опции ANALYZE
и VERBOSE
можно указать, и только в таком порядке, без обрамления списка опций в скобки. До версии PostgreSQL 9.0 поддерживался только синтаксис без скобок. Ожидается, что все новые опции будут поддерживаться только в синтаксисе со скобками.
Параметры
ANALYZE
Выполните команду и покажите фактическое время выполнения и другую статистику. Этот параметр по умолчанию установлен в
FALSE
.VERBOSE
Отображать дополнительную информацию о плане. В частности, включать список выходных столбцов для каждого узла в дереве плана, квалифицировать имена таблиц и функций схемой, всегда помечать переменные в выражениях их псевдонимами в таблице диапазонов и всегда выводить имя каждого триггера, для которого отображаются статистические данные. Идентификатор запроса также будет отображаться, если он был вычислен, см. compute_query_id для получения дополнительной информации. Этот параметр по умолчанию установлен в
FALSE
.COSTS
Включите информацию о предполагаемой стоимости запуска и общей стоимости каждого узла плана, а также о предполагаемом количестве строк и предполагаемой ширине каждой строки. Этот параметр по умолчанию установлен в
TRUE
.SETTINGS
Включите информацию о параметрах конфигурации. В частности, укажите параметры, влияющие на планирование запросов со значением, отличным от встроенного значения по умолчанию. Этот параметр по умолчанию установлен в
FALSE
.BUFFERS
Включите информацию о использовании буфера. В частности, включите количество общих блоков, попаданий, чтений, изменений и записей, количество локальных блоков, попаданий, чтений, изменений и записей, количество временных блоков, прочитанных и записанных, а также время, затраченное на чтение и запись блоков данных файлов и временных файлов (в миллисекундах), если включена опция track_io_timing. Попадание означает, что чтение не было выполнено, потому что блок уже был найден в кеше, когда он был нужен. Общие блоки содержат данные из обычных таблиц и индексов; локальные блоки содержат данные из временных таблиц и индексов; временные блоки содержат временные рабочие данные, используемые при сортировках, хешировании, узлах плана Materialize и подобных случаях. Количество блоков, измененных, указывает на количество исходных блоков, которые были изменены этим запросом; количество блоков, записанных, указывает на количество ранее измененных блоков, вытесненных из кеша этим процессом во время обработки запроса. Количество блоков, отображаемых для узла верхнего уровня, включает блоки, используемые всеми его дочерними узлами. В текстовом формате печатаются только ненулевые значения. По умолчанию установлено значение
FALSE
.WAL
Включите информацию о генерации записей WAL. В частности, укажите количество записей, количество полных изображений страниц (fpi) и объем сгенерированного WAL в байтах. В текстовом формате печатаются только ненулевые значения. Этот параметр может использоваться только при включенном
ANALYZE
. По умолчанию он установлен вFALSE
.TIMING
Включите фактическое время запуска и время, затраченное на каждый узел, в выводе. издержки на повторное чтение системных часов могут замедлить запрос значительно на некоторых системах, поэтому может быть полезно установить этот параметр в
FALSE
, когда требуются только фактические счетчики строк, а не точные времена. Время выполнения всего оператора всегда измеряется, даже когда отключено время на уровне узла с помощью этой опции. Этот параметр может использоваться только при включенномANALYZE
. По умолчанию он установлен вTRUE
.SUMMARY
Включите сводную информацию (например, информацию о суммарном времени выполнения) после плана запроса. Сводная информация включается по умолчанию при использовании
ANALYZE
, но по умолчанию не включается, но может быть включена с помощью этой опции. Время планирования вEXPLAIN EXECUTE
включает время, необходимое для получения плана из кеша и время, необходимое для повторного планирования, если это необходимо.FORMAT
Укажите формат вывода, который может быть TEXT, XML, JSON или YAML. Не текстовый вывод содержит ту же информацию, что и формат текстового вывода, но его легче обрабатывать программам. Этот параметр по умолчанию установлен в
TEXT
.boolean
Определяет, должна ли быть включена или выключена выбранная опция. Вы можете написать
TRUE
,ON
или1
, чтобы включить опцию, иFALSE
,OFF
или0
, чтобы отключить ее. Значениеboolean
также можно опустить, в этом случае предполагаетсяTRUE
.statement
Любой оператор
SELECT
,INSERT
,UPDATE
,DELETE
,MERGE
,VALUES
,EXECUTE
,DECLARE
,CREATE TABLE AS
илиCREATE MATERIALIZED VIEW AS
, план выполнения которого нужно увидеть.
Выводы
Результат команды - это текстовое описание выбранного плана для statement
, при необходимости аннотированное статистикой выполнения. Раздел 14.1 описывает предоставленную информацию.
Примечания
Для того чтобы позволить планировщику запросов Tantor SE принимать обоснованные решения при оптимизации запросов, данные pg_statistic
должны быть актуальными для всех таблиц, используемых в запросе. Обычно этим занимается демон автоочистки автоматически. Но если таблица недавно претерпела значительные изменения в своем содержимом, вам может потребоваться выполнить ручной ANALYZE
вместо ожидания, пока автоочистка синхронизируется с изменениями.
Для измерения временных затрат на выполнение каждого узла в плане выполнения, текущая реализация EXPLAIN ANALYZE
добавляет издержки на профилирование выполнения запроса. В результате выполнение команды EXPLAIN ANALYZE
для запроса иногда может занимать значительно больше времени, чем выполнение самого запроса. Величина издержек зависит от характера запроса и используемой платформы. Наихудший случай возникает для узлов плана, которые сами по себе требуют очень мало времени на выполнение, и на машинах, у которых относительно медленные системные вызовы для получения текущего времени суток.
Примеры
Чтобы показать план для простого запроса к таблице с одним столбцом типа integer
и 10000 строками:
EXPLAIN SELECT * FROM foo; QUERY PLAN --------------------------------------------------------- Seq Scan on foo (cost=0.00..155.00 rows=10000 width=4) (1 row)
Вот тот же запрос с форматированием вывода в JSON:
EXPLAIN (FORMAT JSON) SELECT * FROM foo; QUERY PLAN -------------------------------- [ + { + "Plan": { + "Node Type": "Seq Scan",+ "Relation Name": "foo", + "Alias": "foo", + "Startup Cost": 0.00, + "Total Cost": 155.00, + "Plan Rows": 10000, + "Plan Width": 4 + } + } + ] (1 row)
Если существует индекс и мы используем запрос с индексируемым условием WHERE
, EXPLAIN
может показать другой план:
EXPLAIN SELECT * FROM foo WHERE i = 4; QUERY PLAN -------------------------------------------------------------- Index Scan using fi on foo (cost=0.00..5.98 rows=1 width=4) Index Cond: (i = 4) (2 rows)
Вот тот же запрос, но в формате YAML:
EXPLAIN (FORMAT YAML) SELECT * FROM foo WHERE i='4'; QUERY PLAN ------------------------------- - Plan: + Node Type: "Index Scan" + Scan Direction: "Forward"+ Index Name: "fi" + Relation Name: "foo" + Alias: "foo" + Startup Cost: 0.00 + Total Cost: 5.98 + Plan Rows: 1 + Plan Width: 4 + Index Cond: "(i = 4)" (1 row)
Формат XML оставляется на усмотрение читателя.
Здесь представлен тот же план с подавленными оценками стоимости:
EXPLAIN (COSTS FALSE) SELECT * FROM foo WHERE i = 4; QUERY PLAN ---------------------------- Index Scan using fi on foo Index Cond: (i = 4) (2 rows)
Вот пример плана запроса для запроса с использованием агрегатной функции:
EXPLAIN SELECT sum(i) FROM foo WHERE i < 10; QUERY PLAN --------------------------------------------------------------------- Aggregate (cost=23.93..23.93 rows=1 width=4) -> Index Scan using fi on foo (cost=0.00..23.92 rows=6 width=4) Index Cond: (i < 10) (3 rows)
Вот пример использования EXPLAIN EXECUTE
для отображения плана выполнения подготовленного запроса:
PREPARE query(int, int) AS SELECT sum(bar) FROM test WHERE id > $1 AND id < $2 GROUP BY foo; EXPLAIN ANALYZE EXECUTE query(100, 200); QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ HashAggregate (cost=9.54..9.54 rows=1 width=8) (actual time=0.156..0.161 rows=11 loops=1) Group Key: foo -> Index Scan using test_pkey on test (cost=0.29..9.29 rows=50 width=8) (actual time=0.039..0.091 rows=99 loops=1) Index Cond: ((id > $1) AND (id < $2)) Planning time: 0.197 ms Execution time: 0.225 ms (6 rows)
Конечно, конкретные числа, показанные здесь, зависят от фактического содержимого задействованных таблиц. Также следует отметить, что числа и даже выбранная стратегия запроса могут отличаться в различных версиях Tantor SE из-за улучшений планировщика. Кроме того, команда ANALYZE
использует случайное выборочное исследование для оценки статистики данных; поэтому возможно изменение оценок стоимости после свежего запуска ANALYZE
, даже если фактическое распределение данных в таблице не изменилось.
Совместимость
В стандарте SQL не определен оператор EXPLAIN
.