💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# F.3\. auto_explain `auto_explain`模块自动提供一种慢语句记录执行计划的方法 没有手动运行[EXPLAIN](#calibre_link-575)。 这对于在大型应用程序中跟踪未优化查询尤其有用。 该模块没有提供SQL访问函数。为了使用它,简单加载它到服务器中。 你可以加载它到独立会话中: ``` LOAD 'auto_explain'; ``` (你一定是超级用户才能这样做。) 更典型的用法是预先加载它到 在`postgresql.conf`中[shared_preload_libraries](#calibre_link-576) 包含`auto_explain`的所有会话。然后, 你可以出乎意料地跟踪无论什么时候会发生的慢查询。 当然有价值开销。 ## F.3.1\. 配置参数 有几个配置参数控制`auto_explain`的操作。注意, 缺省操作是什么也不做,如果你想要任何结果, 那么你必须至少设置`auto_explain.log_min_duration`。 `auto_explain.log_min_duration` (`integer`) `auto_explain.log_min_duration`是最小声明执行时间, 以毫秒为单位,将导致语句的计划被记录。设置它为零记录所有计划。 减一(缺省)禁止计划的记录。比如,如果你设置它为`250ms`, 那么运行250ms或者更长时间的所有语句将被记录。只有超级用户可以改变这个设置。 `auto_explain.log_analyze` (`boolean`) `auto_explain.log_analyze`导致`EXPLAIN ANALYZE` 输出,而不是`EXPLAIN`输出,当记录一个执行计划时,被打印。 该参数缺省是关闭的。只有超级用户可以改变这个设置。 > **Note:** 当该参数打开时,为所有执行语句产生每个计划节点时间, 无论他们是否运行足够长的时间来获得记录。 这会对性能产生极其不利的影响。 `auto_explain.log_verbose` (`boolean`) `auto_explain.log_verbose`导致`EXPLAIN VERBOSE` 输出,而不是`EXPLAIN`输出,当记录一个执行计划时,被打印。 该参数缺省是关闭的。只有超级用户可以改变这个设置。 `auto_explain.log_buffers` (`boolean`) `auto_explain.log_buffers`导致 `EXPLAIN(ANALYZE, BUFFERS)` 输出,而不是`EXPLAIN`输出,当记录一个执行计划时,被打印。 该参数缺省是关闭的。只有超级用户可以改变这个设置。 该参数不起作用除非设置`auto_explain.log_analyze`参数。 `auto_explain.log_format` (`enum`) `auto_explain.log_format`选择使用 `EXPLAIN`输出格式。 允许值是`text`,`xml`, `json`和`yaml`。 缺省是text。只有超级用户可以改变这个设置。 `auto_explain.log_timing` (`boolean`) `auto_explain.log_timing`导致`EXPLAIN (ANALYZE, TIMING off)`输出, 而不是`EXPLAIN (ANALYZE)`输出。 反复读取系统时钟的开销可以显著减缓一些系统上的查询,因此当计算实际行时,设置该 参数为关闭是非常有用的,不需要确切时间。 当启动`auto_explain.log_analyze`时,该参数是有效的。 缺省该参数是打开的。只有超级用户可以改变该设置。 `auto_explain.log_nested_statements` (`boolean`) `auto_explain.log_nested_statements`为了记录导致嵌套语句(语句在函数内执行)。 当它是关闭时,只记录顶级查询计划。 该参数缺省是关闭的。 只有超级用户可以改变这个设置。 必须在`postgresql.conf`中设置该参数,典型的用户是: ``` # postgresql.conf shared_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=# 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 loops=1) -> Hash Join (cost=4.17..16.55 rows=92 width=0) (actual time=3.349..3.594 rows=92 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 loops=1) -> Hash (cost=3.02..3.02 rows=92 width=4) (actual time=3.238..3.238 rows=92 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 loops=1) Filter: indisunique ``` ## F.3.3\. 作者 Takahiro Itagaki `<[itagaki.takahiro@oss.ntt.co.jp](mailto:itagaki.takahiro@oss.ntt.co.jp)>`