postgres中的auto_explain

本文档介绍了 PostgreSQL 的 auto_explain 模块,该模块用于自动记录执行时间较长的 SQL 语句的执行计划,以辅助优化查询性能。通过设置如 log_min_duration、log_analyze 等参数,可以控制何时记录执行计划及记录的详细程度。此功能类似于 MySQL 中的慢查询日志,适用于大型应用中追踪未优化的查询。在 postgresql.conf 配置文件中调整相关参数,可以在会话级或数据库级启用 auto_explain,并通过日志查看执行计划和性能统计信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考文档:
http://www.postgres.cn/docs/11/auto-explain.html

该功能,类似mysql中的慢查询  

++++++++++++++++++++++以下内容为官方文档内容++++++++++++++++++++++++

auto_explain模块提供了一种方式来自动记录慢速语句的执行计划,而不需 要手工运行EXPLAIN。这在大型应用中追踪未被优化的查询时有用。

该模块没有提供 SQL 可访问的函数。要使用它,简单地将它载入服务器。你可以把它载入到一个单独的 会话:

LOAD 'auto_explain';

(你必须作为超级用户来这样做)。更典型的用法是通过在postgresql.confsession_preload_librariesshared_preload_libraries参数中包括auto_explain将它预先 载入到某些或者所有会话中。然后你就可以追踪那些出乎意料地慢的查询,而不管它们何时发生。当然为 此会付出一些额外的负荷作为代价。

F.4.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输出)被打印。默认情况下这个参数是关闭的。只有超级用户能够改变这个设置。

注意

当这个参数为打开时,对所有被执行的语句将引起对每个计划节点的计时,不管它们是否运行得足够长以至于被记录。这可能对性能有极度负面的影响。

auto_explain.log_buffers (boolean)

当一个执行计划被记录时,auto_explain.log_buffers控制是否打印 缓冲区使用统计信息;它等效于EXPLAINBUFFERS选项。除非 auto_explain.log_analyze参数被设置,否则这个参数没有效果。这个参数默 认情况下是关闭的。只有超级用户能够改变这个设置。

auto_explain.log_timing (boolean)

当一个执行计划被记录时,auto_explain.log_timing控制是否打印每 个结点上的计时信息;它等效于EXPLAINTIMING选项。重复读取 系统锁的开销在某些系统上可能会显著地拖慢查询,因此当只需要实际行计数而非确切时间时,关闭 这个参数将会很有帮助。只有当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_format (enum)

auto_explain.log_format选择要使用的EXPLAIN输出格式。允许的值是textxmljsonyaml。默认是文本形式。只有超级用户能够改变这个设置。

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.4.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 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

+++++++++++++++++++++++++++++++++end+++++++++++++++++++++++++++++++++++

 --auto_explain ,只在当前会话中生效 

mydb=# load 'auto_explain';
LOAD
mydb=# SET auto_explain.log_min_duration = 0;
SET
mydb=# SET auto_explain.log_analyze = true;
SET
mydb=# SELECT count(*)
mydb-#            FROM pg_class, pg_index
mydb-#            WHERE oid = indrelid AND indisunique;
 count 
-------
   166
(1 row)

mydb=# 

--log中显示的内容

2021-06-22 13:30:54.977 CST [54188] LOG:  duration: 0.712 ms  plan:
        Query Text: SELECT count(*)
                   FROM pg_class, pg_index
                   WHERE oid = indrelid AND indisunique;
        Aggregate  (cost=31.99..32.00 rows=1 width=8) (actual time=0.693..0.695 rows=1 loops=1)
          ->  Hash Join  (cost=24.27..31.58 rows=166 width=0) (actual time=0.445..0.578 rows=166 loops=1)
                Hash Cond: (pg_index.indrelid = pg_class.oid)
                ->  Seq Scan on pg_index  (cost=0.00..6.87 rows=166 width=4) (actual time=0.012..0.082 rows=166 loops=1)
                      Filter: indisunique
                      Rows Removed by Filter: 22
                ->  Hash  (cost=18.01..18.01 rows=501 width=4) (actual time=0.421..0.422 rows=504 loops=1)
                      Buckets: 1024  Batches: 1  Memory Usage: 26kB
                      ->  Seq Scan on pg_class  (cost=0.00..18.01 rows=501 width=4) (actual time=0.011..0.170 rows=504 loops=1)
~
~
~
2021-06-22 13:38:13.061 CST [54188] LOG:  duration: 4692.425 ms  plan:
        Query Text: select count(*) from a;
        Finalize Aggregate  (cost=289935.69..289935.70 rows=1 width=8) (actual time=4679.472..4692.405 rows=1 loops=1)
          ->  Gather  (cost=289935.48..289935.69 rows=2 width=8) (actual time=4678.714..4692.396 rows=3 loops=1)
                Workers Planned: 2
                Workers Launched: 2
                ->  Partial Aggregate  (cost=288935.48..288935.49 rows=1 width=8) (actual time=4661.103..4661.104 rows=1 loops=3)
                      ->  Parallel Seq Scan on a  (cost=0.00..257691.78 rows=12497478 width=0) (actual time=0.071..3006.346 rows=9998000 loops=3)
					  

-- 在数据库级别设置auto_expain,编辑postgresql.conf 

session_preload_libraries = 'auto_explain'
auto_explain.log_min_duration = '3s'

-- 设置后的结果

2021-06-22 13:41:12.877 CST [107469] LOG:  connection authorized: user=postgres database=mydb
2021-06-22 13:41:28.492 CST [107469] LOG:  duration: 3223.121 ms  plan:
        Query Text: select count(*) from a;
        Finalize Aggregate  (cost=289935.69..289935.70 rows=1 width=8)
          ->  Gather  (cost=289935.48..289935.69 rows=2 width=8)
                Workers Planned: 2
                ->  Partial Aggregate  (cost=288935.48..288935.49 rows=1 width=8)
                      ->  Parallel Seq Scan on a  (cost=0.00..257691.78 rows=12497478 width=0)

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值