EXPLAIN#

EXPLAIN

EXPLAIN

EXPLAIN — показать план выполнения оператора

Синтаксис

EXPLAIN [ ( option [, ...] ) ] statement
EXPLAIN [ ANALYZE ] [ VERBOSE ] statement

where option 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.

См. также

ANALYZE