F.28. pg_stat_statements #
pg_stat_statements模块提供了一种机制,用于跟踪服务器执行的所有 SQL 语句的执行统计信息。
由于该模块需要额外的共享内存,因此必须通过在postgresql.conf中将pg_stat_statements加入shared_preload_libraries来加载该模块。这意味着添加或移除此模块都需要重启服务器。
F.28.1. pg_stat_statements 视图
该模块收集的统计信息可通过名为pg_stat_statements的系统视图获取。该视图为每个不同的查询、数据库 ID 和用户 ID 包含一行(最多达到该模块能够跟踪的不同语句数量上限)。视图的列见表 F.22。
该视图以及函数pg_stat_statements_reset只有在通过安装pg_stat_statements扩展而专门安装了它们的数据库中才可用。不过,只要pg_stat_statements模块被装载到服务器中,无论视图是否存在,它都会跟踪该服务器上所有数据库的统计信息。
表 F.22. pg_stat_statements 列
| 名称 | 类型 | 引用 | 描述 |
|---|---|---|---|
userid | oid | | 执行该语句的用户的 OID |
dbid | oid | | 执行该语句所在数据库的 OID |
query | text | 某个代表性语句的文本(最多track_activity_query_size字节) | |
calls | bigint | 执行次数 | |
total_time | double precision | 该语句所花费的总时间,单位为毫秒 | |
rows | bigint | 该语句检索到或影响的总行数 | |
shared_blks_hit | bigint | 该语句的共享块缓存命中总数 | |
shared_blks_read | bigint | 该语句读取的共享块总数 | |
shared_blks_dirtied | bigint | 被该语句弄脏的共享块总数 | |
shared_blks_written | bigint | 该语句写入的共享块总数 | |
local_blks_hit | bigint | 该语句的本地块缓存命中总数 | |
local_blks_read | bigint | 该语句读取的本地块总数 | |
local_blks_dirtied | bigint | 被该语句弄脏的本地块总数 | |
local_blks_written | bigint | 该语句写入的本地块总数 | |
temp_blks_read | bigint | 该语句读取的临时块总数 | |
temp_blks_written | bigint | 该语句写入的临时块总数 | |
blk_read_time | double precision | 该语句读取块所花费的总时间,单位为毫秒(如果启用了track_io_timing,否则为零) | |
blk_write_time | double precision | 该语句写入块所花费的总时间,单位为毫秒(如果启用了track_io_timing,否则为零) |
出于安全原因,非超级用户不允许查看其他用户执行的查询的 SQL 文本。不过,只要该视图已经安装在其数据库中,他们仍然可以查看统计信息。
可进行计划的查询(即 SELECT、INSERT、UPDATE 和 DELETE),只要根据内部哈希计算得出的查询结构相同,就会合并为单条
pg_stat_statements 记录。通常,如果两个查询在语义上等价,仅在查询中出现的字面常量值不同,则会被视为相同。不过,实用命令(即所有其他命令)是严格按照其文本查询字符串进行比较的。
当为了将某个查询与其他查询匹配而忽略常量值时,在
pg_stat_statements 的显示中,该常量会被
? 替换。查询文本的其余部分则是第一个具有该特定哈希值、并与该
pg_stat_statements 记录相关联的查询的文本。
在某些情况下,文本明显不同的查询也可能被合并到同一条
pg_stat_statements 记录中。通常,这只会发生在语义等价的查询之间,但也存在很小的概率由于哈希冲突而把不相关的查询合并为同一条记录。(不过,这种情况不会发生在属于不同用户或不同数据库的查询之间。)
由于哈希值是根据查询经过解析分析后的表示形式计算出来的,相反的情况也可能发生:文本完全相同的查询,如果由于不同的
search_path 设置等因素而具有不同含义,就可能显示为不同的记录。
F.28.2. 函数
F.28.3. 配置参数
-
pg_stat_statements.max(integer) pg_stat_statements.max是该模块跟踪的语句最大数量(即pg_stat_statements视图中的最大行数)。如果观察到的不同语句超过该数量,则执行次数最少的语句信息会被丢弃。默认值为 5000。该参数只能在服务器启动时设置。-
pg_stat_statements.track(enum) pg_stat_statements.track控制该模块统计哪些语句。指定top可跟踪顶层语句(即直接由客户端发出的语句),指定all还会跟踪嵌套语句(例如在函数内调用的语句),而指定none则会禁用语句统计信息收集。默认值为top。只有超级用户可以更改此设置。-
pg_stat_statements.track_utility(boolean) pg_stat_statements.track_utility控制该模块是否跟踪实用命令。实用命令是除SELECT、INSERT、UPDATE和DELETE之外的所有命令。默认值为on。只有超级用户可以更改此设置。-
pg_stat_statements.save(boolean) pg_stat_statements.save指定是否在服务器关闭后保留语句统计信息。如果它为off,则在关闭时不会保存统计信息,并且在服务器启动时也不会重新载入这些统计信息。默认值为on。该参数只能在postgresql.conf文件中或在服务器命令行上设置。
该模块需要约 pg_stat_statements.max *
track_activity_query_size字节的额外共享内存。注意,只要该模块被载入,就会消耗这部分内存,即使
pg_stat_statements.track 被设置为 none 也是如此。
这些参数必须在postgresql.conf中设置。典型用法如下:
# postgresql.conf shared_preload_libraries = 'pg_stat_statements' pg_stat_statements.max = 10000 pg_stat_statements.track = all
F.28.4. 示例输出
bench=# SELECT pg_stat_statements_reset();
$ pgbench -i bench
$ pgbench -c10 -t300 bench
bench=# \x
bench=# SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit /
nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5;
-[ RECORD 1 ]---------------------------------------------------------------------
query | UPDATE pgbench_branches SET bbalance = bbalance + ? WHERE bid = ?;
calls | 3000
total_time | 9609.00100000002
rows | 2836
hit_percent | 99.9778970000200936
-[ RECORD 2 ]---------------------------------------------------------------------
query | UPDATE pgbench_tellers SET tbalance = tbalance + ? WHERE tid = ?;
calls | 3000
total_time | 8015.156
rows | 2990
hit_percent | 99.9731126579631345
-[ RECORD 3 ]---------------------------------------------------------------------
query | copy pgbench_accounts from stdin
calls | 1
total_time | 310.624
rows | 100000
hit_percent | 0.30395136778115501520
-[ RECORD 4 ]---------------------------------------------------------------------
query | UPDATE pgbench_accounts SET abalance = abalance + ? WHERE aid = ?;
calls | 3000
total_time | 271.741999999997
rows | 3000
hit_percent | 93.7968855088209426
-[ RECORD 5 ]---------------------------------------------------------------------
query | alter table pgbench_accounts add primary key (aid)
calls | 1
total_time | 81.42
rows | 0
hit_percent | 34.4947735191637631F.28.5. 作者
Takahiro Itagaki <itagaki.takahiro@oss.ntt.co.jp>。查询规范化功能由 Peter Geoghegan <peter@2ndquadrant.com> 添加。