选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0
历史版本PostgreSQL 9.5 已于 2021 年 2 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本

F.28. pg_stat_statements #

pg_stat_statements模块提供了一种机制,用于跟踪服务器执行的所有 SQL 语句的执行统计信息。

由于该模块需要额外的共享内存,因此必须通过在postgresql.conf中将pg_stat_statements加入shared_preload_libraries来加载该模块。这意味着添加或移除此模块都需要重启服务器。

启用pg_stat_statements后,它会跟踪该服务器上所有数据库的统计信息。为了访问和操作这些统计信息,该模块提供了视图pg_stat_statements,以及实用函数pg_stat_statements_resetpg_stat_statements。这些对象并非全局可用,但可以通过CREATE EXTENSION pg_stat_statements在特定数据库中启用。

F.28.1. pg_stat_statements 视图

该模块收集的统计信息可通过名为pg_stat_statements的视图获取。该视图为每个不同的数据库 ID、用户 ID 和查询 ID 包含一行(最多达到该模块能够跟踪的不同语句数量上限)。视图的列见表 F.22

表 F.22. pg_stat_statements

名称 类型 引用 描述
userid oid pg_authid.oid 执行该语句的用户的 OID
dbid oid pg_database.oid 执行该语句所在数据库的 OID
queryid bigint   根据语句的解析树计算的内部哈希码
query text   某个代表性语句的文本
calls bigint   执行次数
total_time double precision   该语句所花费的总时间,单位为毫秒
min_time double precision   该语句所花费的最短时间,单位为毫秒
max_time double precision   该语句所花费的最长时间,单位为毫秒
mean_time double precision   该语句所花费的平均时间,单位为毫秒
stddev_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 文本或queryid。不过,只要该视图已经安装在其数据库中,他们仍然可以查看统计信息。

可进行计划的查询(即 SELECTINSERTUPDATEDELETE),只要根据内部哈希计算 得出的查询结构相同,就会合并为单条 pg_stat_statements 记录。通常,如果两个查询在语义上等价, 仅在查询中出现的字面常量值不同,则会被视为相同。不过,实用命令(即所有其他命令) 是严格按照其文本查询字符串进行比较的。

当为了将某个查询与其他查询匹配而忽略常量值时,在 pg_stat_statements 的显示中,该常量会被 ? 替换。查询文本的其余部分则取自第一个具有该特定 queryid 哈希值、并与该 pg_stat_statements 记录相关联的查询。

在某些情况下,文本明显不同的查询也可能被合并到同一条 pg_stat_statements 记录中。通常,这只会发生在 语义等价的查询之间,但也存在很小的概率由于哈希冲突而把不相关的查询合并 为同一条记录。(不过,这种情况不会发生在属于不同用户或不同数据库的查询之间。)

由于 queryid 哈希值是根据查询经过解析分析后的表示形式计算出来的, 相反的情况也可能发生:文本完全相同的查询,如果由于不同的 search_path 设置等因素而具有不同含义,就可能显示为不同的记录。

pg_stat_statements 的使用者可能希望使用 queryid(也许再结合 dbiduserid)作为每条记录比查询文本更稳定、 更可靠的标识符。不过,必须理解的是, queryid 哈希值的稳定性只得到有限保证。 由于该标识符源自解析分析后的语法树,它的取值除其他因素外,还取决于该表示形式中出现的内部对象标识符。 这会带来一些反直觉的结果。例如,如果两次查询执行之间, 所引用的某张表被删除并重新创建,那么 pg_stat_statements 会将两条看似完全相同的查询视为不同。 哈希过程也对机器架构差异以及平台的其他方面很敏感。 此外,也不能安全地假设 queryid 会在 PostgreSQL 的主版本之间保持稳定。

通常可以假定queryid值是稳定且可比较的,前提是底层服务器版本和目录元数据细节始终完全相同。参与基于物理 WAL 重放的复制的两个服务器,对于同一查询可以期待具有相同的queryid值。然而,逻辑复制方案并不承诺在所有相关细节上保持副本完全一致,因此queryid不适合作为在一组逻辑副本之间累积开销的标识符。如有疑问,建议直接测试。

代表性查询文本保存在外部磁盘文件中,因此不消耗共享内存。即使非常长的查询文本也可以成功存储。 不过,如果积累了很多长查询文本,该外部文件可能会膨胀到难以管理的大小。若发生这种情况, 作为一种恢复措施,pg_stat_statements 可能会选择丢弃这些查询文本, 这样 pg_stat_statements 视图中的现有记录都会显示 query 字段为 null,但与各个 queryid 相关的统计信息仍会保留。如果发生这种情况,可考虑减小 pg_stat_statements.max 以避免再次发生。

F.28.2. 函数

pg_stat_statements_reset() returns void

pg_stat_statements_reset会丢弃到目前为止由pg_stat_statements收集的所有统计信息。默认情况下,只有超级用户可以执行此函数。

pg_stat_statements(showtext boolean) returns setof record

pg_stat_statements 视图是根据一个同名的 pg_stat_statements 函数定义的。客户端也可以直接调用 pg_stat_statements 函数,并通过指定 showtext := false 来省略查询文本(也就是说,与该视图 query 列对应的 OUT 参数会返回 null)。 这一特性旨在支持某些外部工具,这些工具可能希望避免反复获取长度不定的查询文本所带来的开销。 这些工具可以自行缓存每条记录第一次观察到的查询文本,因为这正是 pg_stat_statements 本身所做的事情,然后只在需要时再获取查询文本。 由于服务器会把查询文本存储在文件中,这种做法在反复检查 pg_stat_statements 数据时可以减少物理 I/O。

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 控制该模块是否跟踪实用命令。 实用命令是除 SELECTINSERTUPDATEDELETE 之外的所有命令。 默认值为 on。 只有超级用户可以更改此设置。

pg_stat_statements.save (boolean)

pg_stat_statements.save 指定是否在服务器关闭后保留语句统计信息。 如果它为 off,则在关闭时不会保存统计信息,并且在服务器启动时也不会重新载入这些统计信息。 默认值为 on。 该参数只能在 postgresql.conf 文件中或在服务器命令行上设置。

该模块需要与 pg_stat_statements.max 成比例的额外共享内存。 注意,只要该模块被载入,就会消耗这部分内存,即使 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.4947735191637631

F.28.5. 作者

Takahiro Itagaki 。 查询规范化功能由 Peter Geoghegan 添加。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。