PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

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

F.3.1. 配置参数
F.3.2. 示例
F.3.3. 作者

auto_explain 模块提供自动记录慢语句执行计划的手段,无需手动运行 EXPLAIN。这对于排查大型应用中未经优化的查询特别有帮助。

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

LOAD 'auto_explain';

(必须是超级用户才能这样做。)更典型的用法是在 postgresql.conf 中将 auto_explain 加入 session_preload_libraries 或 shared_preload_libraries,从而将其预加载到部分或全部会话。这样,无论意外变慢的查询何时发生,你都能跟踪到它。当然,这会带来一定的开销。

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 控制记录执行计划时是否打印缓冲区使用统计;它等效于 EXPLAIN 的 BUFFERS 选项。除非启用了 auto_explain.log_analyze,否则该参数没有效果。该参数默认关闭。只有超级用户可以更改此设置。

auto_explain.log_wal (boolean) #

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

auto_explain.log_timing (boolean) #

auto_explain.log_timing 控制记录执行计划时是否打印每个节点的计时信息;它等效于 EXPLAIN 的 TIMING 选项。在某些系统上,反复读取系统时钟的开销会显著拖慢查询,因此当只需要实际行数而非精确时间时,将该参数关闭可能有用。除非启用了 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 控制记录执行计划时是否打印详细细节;它等效于 EXPLAIN 的 VERBOSE 选项。该参数默认关闭。只有超级用户可以更改此设置。

auto_explain.log_settings (boolean) #

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

auto_explain.log_format (enum) #

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

auto_explain.log_level (enum) #

auto_explain.log_level 选择 auto_explain 记录查询计划时使用的日志级别。有效值为 DEBUG5、DEBUG4、DEBUG3、DEBUG2、DEBUG1、INFO、NOTICE、WARNING 与 LOG。默认值为 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