首页/数据/SQL 速查/auto_explain 自动记录慢查询计划
性能与执行计划72 条

auto_explain 自动记录慢查询计划

把超过阈值的语句连同执行计划写进日志:事后分析线上慢查询时不用手动复现。

SQL 速查数据更新于 2026-10-13

这个扩展做什么

auto_explain 是 PostgreSQL 的扩展模块:语句耗时超过阈值时,自动把它的执行计划写进日志,还可以附带实测耗时、行数与缓冲区统计。事后分析线上慢查询时不用再手工复现。它通过 shared_preload_libraries 预加载,属于服务端级别的诊断工具。

基本信息

生效方式shared_preload_libraries 需重启;其余参数支持会话级 SET 或改配置后 reload
记录阈值auto_explain.log_min_duration 决定记录哪些语句
实测数据log_analyze 按 ANALYZE 方式采集,有少量额外开销
缓冲区log_buffers 附带缓冲区统计,定位读放大
本地调试会话内把阈值设为 0,可记录当前会话全部语句

典型使用场景

  • 线上慢查询的事后分析,不用手工复现
  • 排查只在特定参数下才慢的语句
  • 定位读放大,看是共享块命中还是读盘
  • 对比一次发布前后的计划差异
  • 测试环境用会话级设置,只记录自己的语句

全局配置

全局配置
shared_preload_libraries = 'auto_explain'   # 必须预加载,改完要重启实例
auto_explain.log_min_duration = '1s'        # 记录超过 1 秒的语句,-1 表示关闭
auto_explain.log_analyze = on               # 附带实际耗时与行数
auto_explain.log_buffers = on               # 附带缓冲区统计
auto_explain.log_nested_statements = on     # 也记录函数内部的语句

会话级调试

会话级调试
-- 只在当前会话生效,适合在测试环境复现问题
SET auto_explain.log_min_duration = 0;   -- 记录本会话的全部语句
SET auto_explain.log_analyze = on;
SET auto_explain.log_buffers = on;

-- 确认日志写到哪里,再去对应目录里找
SHOW log_directory;
SHOW log_filename;

关键参数读法

参数作用注意
log_min_duration记录多久以上的语句设得太低会让日志爆炸
log_analyze用 ANALYZE 方式采集实测数据有额外开销,高峰期慎用
log_buffers记录缓冲区使用情况用来判断读放大与缓存命中
log_nested_statements记录函数内部语句排查函数里藏着的慢查询
log_format(12+)输出格式,可选结构化格式需要程序化解析时优先选 json
log_analyze 会带来额外开销:每记录一条都要采集实测数据,如果对所有语句都开启会把负载放大。只在排查期打开,并用阈值把范围限制在真正慢的语句上。
忘了预加载就什么输出都没有:只把 log_min_duration 调小、却没把 auto_explain 放进 shared_preload_libraries 并重启,模块根本没加载,容易误判成「没有慢查询」。

易错点

  • 日志量失控:阈值设得过低或对高频语句记录,日志迅速膨胀,磁盘与解析成本都上升
  • 忘记它需要预加载:只改阈值而没加载模块,不会有任何输出,容易误判为没有慢查询
  • 长期开启 log_analyze:每条记录都要采集实测数据,额外开销持续累积,排查期结束就该关掉
  • 只看日志里的计划不看参数:同一语句不同参数的计划可能完全不同,分析时要连带看日志中的参数值
  • 把自动记录的计划当成绝对结论:计划会随统计信息与数据分布变化,要结合当时的负载一起判断

数据来源与参考

  • PostgreSQL Documentation · auto_explain
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌