受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

F.3. auto_explain — 记录慢查询的执行计划 #

auto_explain模块提供了一种自动记录慢语句执行计划的方法,而无须手工运行EXPLAIN。这对于在大型应用中追查未优化的查询尤其有帮助。

该模块不提供可通过 SQL 访问的函数。要使用它,只需将其加载到服务器中。可以将其加载到单个会话中:

LOAD 'auto_explain';

(要这样做,必须是超级用户。)更典型的用法是,在postgresql.conf中的session_preload_librariesshared_preload_libraries里包含auto_explain,从而将其预加载到部分或全部会话中。这样,无论查询何时意外变慢,都可以追踪到它们。当然,这要付出额外开销。

F.3.1. 配置参数 #

有若干配置参数可控制auto_explain的行为。注意,其默认行为是什么都不做,因此如果希望得到任何结果,至少必须设置auto_explain.log_min_duration

auto_explain.log_min_duration (integer) #

auto_explain.log_min_duration是会导致记录该语句计划的最小语句执行时间,单位为毫秒。将其设为0会记录所有计划。-1(默认值)会禁用计划记录。例如,如果将其设为250ms,则所有运行 250ms 或更久的语句都会被记录。只有超级用户可以更改此设置。

auto_explain.log_parameter_max_length (integer) #

auto_explain.log_parameter_max_length控制查询参数值的记录。取值为-1(默认值)时,会完整记录参数值。0会禁用参数值记录。大于零的值会将每个参数值截断为指定字节数。只有超级用户可以更改此设置。

auto_explain.log_analyze (boolean) #

auto_explain.log_analyze使得在记录执行计划时输出EXPLAIN ANALYZE,而不只是输出EXPLAIN。该参数默认关闭。只有超级用户可以更改此设置。

Note

当该参数开启时,所有已执行语句都会对每个计划节点计时,无论它们是否实际运行得足够久而最终被记录。这可能对性能造成极其负面的影响。关闭auto_explain.log_timing可以缓解性能开销,但代价是获得的信息会更少。

auto_explain.log_buffers (boolean) #

auto_explain.log_buffers控制在记录执行计划时是否打印缓冲区使用统计信息;它等效于EXPLAINBUFFERS选项。除非启用auto_explain.log_analyze,否则该参数没有效果。该参数默认关闭。只有超级用户可以更改此设置。

auto_explain.log_wal (boolean) #

auto_explain.log_wal控制在记录执行计划时是否打印 WAL 使用统计信息;它等效于EXPLAINWAL选项。除非启用auto_explain.log_analyze,否则该参数没有效果。该参数默认关闭。只有超级用户可以更改此设置。

auto_explain.log_timing (boolean) #

auto_explain.log_timing控制在记录执行计划时是否打印每个计划节点的计时信息;它等效于EXPLAINTIMING选项。在某些系统上,反复读取系统时钟的开销可能会显著拖慢查询,因此如果只需要实际行计数而不需要精确时间,将该参数设为 off 可能会有用。除非启用auto_explain.log_analyze,否则该参数没有效果。该参数默认开启。只有超级用户可以更改此设置。

auto_explain.log_triggers (boolean) #

auto_explain.log_triggers使得在记录执行计划时包含触发器执行统计信息。除非启用auto_explain.log_analyze,否则该参数没有效果。该参数默认关闭。只有超级用户可以更改此设置。

auto_explain.log_verbose (boolean) #

auto_explain.log_verbose控制在记录执行计划时是否打印详细信息;它等效于EXPLAINVERBOSE选项。该参数默认关闭。只有超级用户可以更改此设置。

auto_explain.log_settings (boolean) #

auto_explain.log_settings控制在记录执行计划时是否打印已修改配置选项的相关信息。输出中只包含影响查询规划且其值不同于内置默认值的选项。该参数默认关闭。只有超级用户可以更改此设置。

auto_explain.log_format (enum) #

auto_explain.log_format选择要使用的EXPLAIN输出格式。允许的值有textxmljsonyaml。默认值为 text。只有超级用户可以更改此设置。

auto_explain.log_level (enum) #

auto_explain.log_level选择 auto_explain 记录查询计划时使用的日志级别。有效值为DEBUG5DEBUG4DEBUG3DEBUG2DEBUG1INFONOTICEWARNINGLOG。默认值为LOG。只有超级用户可以更改此设置。

auto_explain.log_nested_statements (boolean) #

auto_explain.log_nested_statements使嵌套语句(在函数内部执行的语句)也会被纳入记录考虑范围。关闭该参数时,只记录顶层查询计划。该参数默认关闭。只有超级用户可以更改此设置。

auto_explain.sample_rate (real) #

auto_explain.sample_rate使 auto_explain 在每个会话中只解释一部分语句。默认值为 1,表示解释所有查询。对于嵌套语句,要么全部解释,要么全部不解释。只有超级用户可以更改此设置。

在通常用法中,这些参数都在postgresql.conf中设置,尽管超级用户也可以在自己的会话中动态修改它们。典型的用法可能是:

# postgresql.conf
session_preload_libraries = 'auto_explain'

auto_explain.log_min_duration = '3s'

F.3.2. 示例 #

postgres=# LOAD 'auto_explain';
postgres=# SET auto_explain.log_min_duration = 0;
postgres=# SET auto_explain.log_analyze = true;
postgres=# SELECT count(*)
           FROM pg_class, pg_index
           WHERE oid = indrelid AND indisunique;

这可能产生如下日志输出:

LOG:  duration: 3.651 ms  plan:
  Query Text: SELECT count(*)
              FROM pg_class, pg_index
              WHERE oid = indrelid AND indisunique;
  Aggregate  (cost=16.79..16.80 rows=1 width=0) (actual time=3.626..3.627 rows=1.00 loops=1)
    ->  Hash Join  (cost=4.17..16.55 rows=92 width=0) (actual time=3.349..3.594 rows=92.00 loops=1)
          Hash Cond: (pg_class.oid = pg_index.indrelid)
          ->  Seq Scan on pg_class  (cost=0.00..9.55 rows=255 width=4) (actual time=0.016..0.140 rows=255.00 loops=1)
          ->  Hash  (cost=3.02..3.02 rows=92 width=4) (actual time=3.238..3.238 rows=92.00 loops=1)
                Buckets: 1024  Batches: 1  Memory Usage: 4kB
                ->  Seq Scan on pg_index  (cost=0.00..3.02 rows=92 width=4) (actual time=0.008..3.187 rows=92.00 loops=1)
                      Filter: indisunique

F.3.3. 作者 #

Takahiro Itagaki

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。