Перейти к основному содержимому

Функции статистики планов выполнения запросов

Функции, представленные в данном разделе, реализованы в рамках функциональности «Управление планами запросов».

pg_store_plans_reset()

Удаляет всю статистику, собранную на данный момент расширением pg_store_plans. По умолчанию эту функцию могут запускать только суперпользователи.

Синтаксис:

.pg_store_plans_reset()
RETURNS void

Входные параметры:

Отсутствуют.

Возвращаемые значения:

Отсутствуют. В случае успешного выполнения функции значение вернется пустым.

Пример использования:

SELECT pg_store_plans_reset();

pg_store_plans()

Формирует представление pg_store_plans.

Синтаксис:

pg_store_plans(OUT userid oid, OUT dbid oid, OUT queryid bigint, OUT planid bigint, OUT plan text, 
OUT calls bigint, OUT total_time double precision, OUT min_time double precision, OUT max_time double precision,
OUT mean_time double precision, OUT stddev_time double precision, OUT rows bigint, OUT shared_blks_hit bigint,
OUT shared_blks_read bigint, OUT shared_blks_dirtied bigint, OUT shared_blks_written bigint, OUT local_blks_hit bigint,
OUT local_blks_read bigint, OUT local_blks_dirtied bigint, OUT local_blks_written bigint, OUT temp_blks_read bigint,
OUT temp_blks_written bigint, OUT blk_read_time double precision, OUT blk_write_time double precision,
OUT temp_blk_read_time double precision, OUT temp_blk_write_time double precision, OUT first_call timestamp with time zone,
OUT last_call timestamp with time zone)
RETURNS SETOF record

Входные параметры:

Отсутствуют.

Возвращаемые значения:

Название поляТип значенияОписание
dbidoidOID пользователя, который выполнил запрос
queryidbigintOID базы данных, в которой был выполнен запрос
planidbigintИдентификатор запроса, сгенерированный ядром или рассчитанный расширением. Позволяет получить текст запроса из расширения pg_stat_statements
plantextХеш-код плана, вычисляемый на основе нормализованного представления плана
callsbigintТекст плана запроса. Формат задается параметром конфигурации pg_store_plans.plan_format
total_timedouble precisionКоличество выполнений запросов с данным планом
min_timedouble precisionОбщее время, затраченное на выполнение запросов с использованием плана, в миллисекундах
max_timedouble precisionМинимальное время, затраченное на выполнение запроса с использованием плана, в миллисекундах
mean_timedouble precisionМаксимальное время, затраченное на выполнение запроса с использованием плана, в миллисекундах
stddev_timedouble precisionСреднее время, затраченное на выполнение запроса с использованием плана, в миллисекундах
rowsbigintСтандартное отклонение времени, затраченное на выполнение запроса с использованием плана, в миллисекундах
shared_blks_hitbigintОбщее количество строк, извлеченных или затронутых оператором с использованием плана
shared_blks_readbigintКоличество обращений к блокам в общем кеше («попадание» в кеш) с помощью запроса, использующего данный план
shared_blks_dirtiedbigintКоличество блоков, прочитанных из общего буферного кеша запросом с использованием данного плана
shared_blks_writtenbigintОбщее количество измененных, но не сохраненных запросом файлов сегментов данных («dirty blocks»)
local_blks_hitbigintОбщее количество блоков, записанных запросом с использованием данного плана
local_blks_readbigintОбщее количество обращений к блокам локального кеша («попаданий» в кеш) запроса, использующего данный план
local_blks_dirtiedbigintОбщее количество блоков локального кеша, измененных, но не сохраненных запросом файлов сегментов данных («dirty blocks»)
local_blks_writtenbigintОбщее количество блоков локального кеша, записанных запросом с использованием данного плана
temp_blks_readbigintОбщее количество блоков локального кеша, записанных запросом с использованием данного плана
temp_blks_writtenbigintОбщее количество временных блоков, прочитанных запросом с использованием данного плана
blk_read_timedouble precisionОбщее время, затраченное запросом, использующим данный план, на чтение блоков, в миллисекундах (если включена опция track_io_timing, в противном случае равно нулю)
blk_write_timedouble precisionОбщее время, затраченное запросом, использующим данный план, на запись блоков, в миллисекундах (если включена опция track_io_timing, в противном случае равно нулю)
temp_blk_read_timedouble precisionОбщее время, затраченное запросом, использующим данный план, на чтение блоков временных файлов, в миллисекундах (если включена опция track_io_timing, в противном случае равно нулю)
temp_blk_write_timedouble precisionОбщее время, затраченное запросом, использующим данный план, на запись блоков временных файлов, в миллисекундах (если включена опция track_io_timing, в противном случае равно нулю)
first_calltimestamp with time zoneВременная метка для первого вызова запроса с использованием этого плана
last_calltimestamp with time zoneВременная метка для последнего вызова запроса с использованием этого плана

Пример использования:

Вызов представления для просмотра последней записи:

SELECT * FROM public.pg_store_plans LIMIT 1 \gx

Пример вывода:

-[ RECORD 1 ]-------+-------------------------------------------------------------------------------------------------------------------------------
userid | 17972
dbid | 17973
queryid | 457670357126543958
planid | 2871964447
plan | Nested Loop Left (cost=1.60..51.69 rows=2 width=392) +
| -> Nested Loop (cost=1.46..51.34 rows=2 width=398) +
| -> Nested Loop (cost=1.18..50.74 rows=2 width=400) +
| -> Nested Loop (cost=1.05..50.42 rows=2 width=276) +
| Join Filter: ((1) = a.attnum) +
| -> Hash Join (cost=0.77..28.43 rows=28 width=144) +
| Hash Cond: (c.oid = ((18103))::oid) +
| -> Seq Scan on pg_class c (cost=0.00..25.64 rows=464 width=136) +
| -> Hash (cost=0.42..0.42 rows=28 width=8) +
| -> Append (cost=0.00..0.42 rows=28 width=8) +
| Subplans Removed: 0 +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Result (cost=0.00..0.01 rows=1 width=8) +
| -> Index Scan using pg_attribute_relid_attnum_index on pg_attribute a (cost=0.28..0.69 rows=8 width=140)+
| Index Cond: (attrelid = c.oid) +
| -> Index Scan using pg_namespace_oid_index on pg_namespace n (cost=0.13..0.15 rows=1 width=132) +
| Index Cond: (oid = c.relnamespace) +
| -> Index Scan using pg_type_oid_index on pg_type t (cost=0.28..0.30 rows=1 width=6) +
| Index Cond: (oid = a.atttypid) +
| -> Index Scan using pg_attrdef_adrelid_adnum_index on pg_attrdef d (cost=0.14..0.16 rows=1 width=38) +
| Index Cond: ((adrelid = a.attrelid) AND (adnum = a.attnum))
calls | 1
total_time | 0.364489
min_time | 0.364489
max_time | 0.364489
mean_time | 0.364489
stddev_time | 0
rows | 28
shared_blks_hit | 298
shared_blks_read | 0
shared_blks_dirtied | 0
shared_blks_written | 0
local_blks_hit | 0
local_blks_read | 0
local_blks_dirtied | 0
local_blks_written | 0
temp_blks_read | 0
temp_blks_written | 0
blk_read_time | 0
blk_write_time | 0
temp_blk_read_time | 0
temp_blk_write_time | 0
first_call | 2025-10-15 12:49:00.929133+03
last_call | 2025-10-15 12:49:00.929133+03
*/

pg_store_plans_info()

Формирует представление pg_store_plans_info.

Синтаксис:

pg_store_plans_info(OUT dealloc bigint, OUT stats_reset timestamp with time zone)
RETURNS record

Входные параметры:

Отсутствуют.

Возвращаемые значения:

Название поляТип значенияОписание
deallocbigintОбщее количество раз, когда записи pg_store_plans о наименее выполняемых операторах освобождались, поскольку наблюдалось больше отдельных операторов, чем pg_store_plans.max
stats_resettimestamp with time zoneВремя последнего сброса всей статистики в представлении pg_store_plans

Пример использования:

SELECT * FROM pg_store_plans_info;

Пример вывода:

dealloc|stats_reset                  |
-------+-----------------------------+
0|2025-10-15 12:52:29.313 +0300|

pg_store_plans_hash_query()

Вычисляет хеш-значение текста запроса. Тот же алгоритм используется для вычисления queryid в pg_store_plans, поэтому эту функцию можно использовать для объединения с pg_store_plans (например, для поиска планов по тексту запроса).

Синтаксис:

pg_store_plans_hash_query(text)
RETURNS oid

Входные параметры:

Название параметраТип значенияОписание
texttextТекст запроса

Возвращаемое значение:

Название поляТип значенияОписание
OIDoidID пользователя, выполнившего запрос

Пример использования:

SELECT pg_store_plans_hash_query('SELECT * FROM test_table_store_plans WHERE id = 13;');

Пример вывода:

pg_store_plans_hash_query|
-------------------------+
3209944600|

Заметки об использовании:

Внимание!

Deprecated-функцияpg_store_plans_hash_query(query text) в настоящее время не используется, поскольку в ядро PostgreSQL включено расширение pg_stat_statements, из которого можно получать тексты запросов. Более того, функция расчета queryid была изменена в пользу алгоритма pg_stat_statements для совместимости с ним, а результат расчета данной функции стал некорректным.

pg_store_plans_textplan()

Генерирует обычное текстовое представление из необработанного представления плана в pg_store_plans, которое отображается, когда pg_store_plans.plan_formats = 'raw'. Поскольку текст результирующего плана генерируется на основе представления в формате JSON, он может отличаться от того, что полученного непосредственно из командной строки при помощи EXPLAIN.

Синтаксис:

pg_store_plans_textplan(text)
RETURNS text

Входные параметры:

Название поляТип значенияОписание
texttextТекст запроса из необработанного представления плана

Возвращаемое значение:

Название поляТип значенияОписание
texttextОбычное текстовое представление запроса

Пример использования:

SELECT pg_store_plans_textplan(plan) FROM pg_store_plans WHERE queryid = 8843516759257309882;

Пример вывода:


pg_store_plans_textplan
----------------------------------------------------------------------------------------------------------
Nested Loop Left (cost=0.55..5.10 rows=1 width=430) +
-> Index Scan using pg_class_relname_nsp_index on pg_class c (cost=0.27..2.50 rows=1 width=336) +
Index Cond: ((relname = 'pg_settings'::text) AND (relnamespace = '11'::oid)) +
Filter: (relkind <> ALL ('{i,I,c}'::"char"[])) +
-> Index Scan using pg_description_o_c_o_index on pg_description d (cost=0.28..2.50 rows=1 width=30)+
Index Cond: ((objoid = c.oid) AND (classoid = '1259'::oid) AND (objsubid = 0))
(1 row)

pg_store_plans_jsonplan()

Преобразует JSON-план в коротком формате (или формате raw) в обычный формат JSON. Краткий формат JSON - это внутренний формат для плана в pg_store_plans, который отображается, когда pg_store_plans.plan_formats = 'raw'.

Синтаксис:

pg_store_plans_jsonplan(text)
RETURNS text

Входные параметры:

Название поляТип значенияОписание
texttextJSON-план в коротком формате

Возвращаемое значение:

Название поляТип значенияОписание
texttextОбычный JSON-формат запроса

Пример использования:

SELECT pg_store_plans_jsonplan(plan) FROM pg_store_plans WHERE queryid = 8843516759257309882;

Пример вывода:

{
"Plan": {
"Node Type": "Nested Loop",
"Parallel Aware": false,
"Async Capable": false,
"Join Type": "Left",
"Startup Cost": 0.55,
"Total Cost": 5.10,
"Plan Rows": 1,
"Plan Width": 430,
"Inner Unique": true,
"Plans": [
{
"Node Type": "Index Scan",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Scan Direction": "Forward",
"Index Name": "pg_class_relname_nsp_index",
"Relation Name": "pg_class",
"Alias": "c",
"Startup Cost": 0.27,
"Total Cost": 2.50,
"Plan Rows": 1,
"Plan Width": 336,
"Index Cond": "((relname = 'pg_settings'::text) AND (relnamespace = '11'::oid))",
"Filter": "(relkind <> ALL ('{i,I,c}'::\"char\"[]))"
},
{
"Node Type": "Index Scan",
"Parent Relationship": "Inner",
"Parallel Aware": false,
"Async Capable": false,
"Scan Direction": "Forward",
"Index Name": "pg_description_o_c_o_index",
"Relation Name": "pg_description",
"Alias": "d",
"Startup Cost": 0.28,
"Total Cost": 2.50,
"Plan Rows": 1,
"Plan Width": 30,
"Index Cond": "((objoid = c.oid) AND (classoid = '1259'::oid) AND (objsubid = 0))"
}
]
}
}

pg_store_plans_xmlplan()

Генерирует XML-представления из необработанного представления плана в pg_store_plans, которое отображается, когда pg_store_plans.plan_formats = 'raw'.

Синтаксис:

pg_store_plans_xmlplan(text)
RETURNS text

Входные параметры:

Название поляТип значенияОписание
texttextНеобработанное представление запроса

Возвращаемое значение:

Название поляТип значенияОписание
texttextXML-представление запроса

Пример использования:

SELECT pg_store_plans_xmlplan(plan) FROM pg_store_plans WHERE queryid = 8843516759257309882;

Пример вывода:

<explain xmlns="http://www.postgresql.org/2009/explain">
<Query>
<Plan>
<Node-Type>Nested Loop</Node-Type>
<Parallel-Aware>false</Parallel-Aware>
<Async-Capable>false</Async-Capable>
<Join-Type>Left</Join-Type>
<Startup-Cost>0.55</Startup-Cost>
<Total-Cost>5.10</Total-Cost>
<Plan-Rows>1</Plan-Rows>
<Plan-Width>430</Plan-Width>
<Inner-Unique>true</Inner-Unique>
<Plans>
<Plan>
<Node-Type>Index Scan</Node-Type>
<Parent-Relationship>Outer</Parent-Relationship>
<Parallel-Aware>false</Parallel-Aware>
<Async-Capable>false</Async-Capable>
<Scan-Direction>Forward</Scan-Direction>
<Index-Name>pg_class_relname_nsp_index</Index-Name>
<Relation-Name>pg_class</Relation-Name>
<Alias>c</Alias>
<Startup-Cost>0.27</Startup-Cost>
<Total-Cost>2.50</Total-Cost>
<Plan-Rows>1</Plan-Rows>
<Plan-Width>336</Plan-Width>
<Index-Cond>((relname = 'pg_settings'::text) AND (relnamespace = '11'::oid))</Index-Cond>
<Filter>(relkind &lt;&gt; ALL ('{i,I,c}'::"char"[]))</Filter>
</Plan>
<Plan>
<Node-Type>Index Scan</Node-Type>
<Parent-Relationship>Inner</Parent-Relationship>
<Parallel-Aware>false</Parallel-Aware>
<Async-Capable>false</Async-Capable>
<Scan-Direction>Forward</Scan-Direction>
<Index-Name>pg_description_o_c_o_index</Index-Name>
<Relation-Name>pg_description</Relation-Name>
<Alias>d</Alias>
<Startup-Cost>0.28</Startup-Cost>
<Total-Cost>2.50</Total-Cost>
<Plan-Rows>1</Plan-Rows>
<Plan-Width>30</Plan-Width>
<Index-Cond>((objoid = c.oid) AND (classoid = '1259'::oid) AND (objsubid = 0))</Index-Cond>
</Plan>
</Plans>
</Plan>
</Query>
</explain>

pg_store_plans_yamlplan()

Генерирует YAML-представления из необработанного представления плана в pg_store_plans, которое отображается, когда pg_store_plans.plan_formats = 'raw'.

Синтаксис:

pg_store_plans_yamlplan(text)
RETURNS text

Входные параметры:

Название поляТип значенияОписание
texttextНеобработанное представление запроса

Возвращаемое значение:

Название поляТип значенияОписание
texttextYAML-представление запроса

Пример использования:

SELECT pg_store_plans_yamlplan(plan) FROM pg_store_plans WHERE queryid = 8843516759257309882;

Пример вывода:

- Plan:
Node Type: "Nested Loop"
Parallel Aware: false
Async Capable: false
Join Type: "Left"
Startup Cost: 0.55
Total Cost: 5.10
Plan Rows: 1
Plan Width: 430
Inner Unique: true
Plans:
- Node Type: "Index Scan"
Parent Relationship: "Outer"
Parallel Aware: false
Async Capable: false
Scan Direction: "Forward"
Index Name: "pg_class_relname_nsp_index"
Relation Name: "pg_class"
Alias: "c"
Startup Cost: 0.27
Total Cost: 2.50
Plan Rows: 1
Plan Width: 336
Index Cond: "((relname = 'pg_settings'::text) AND (relnamespace = '11'::oid))"
Filter: "(relkind <> ALL ('{i,I,c}'::\"char\"[]))"
- Node Type: "Index Scan"
Parent Relationship: "Inner"
Parallel Aware: false
Async Capable: false
Scan Direction: "Forward"
Index Name: "pg_description_o_c_o_index"
Relation Name: "pg_description"
Alias: "d"
Startup Cost: 0.28
Total Cost: 2.50
Plan Rows: 1
Plan Width: 30
Index Cond: "((objoid = c.oid) AND (classoid = '1259'::oid) AND (objsubid = 0))"