首页/数据/SQL 速查/PG EXPLAIN ANALYZE 与 BUFFERS
性能与执行计划72 条

PG EXPLAIN ANALYZE 与 BUFFERS

ANALYZE 真正执行查询并给出实际行数、耗时与循环次数;BUFFERS 附加共享缓存命中与磁盘读取统计。

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

PG 的 EXPLAIN ANALYZE 是什么

PostgreSQL 的 EXPLAIN 加上 ANALYZE 会真正执行语句,给出每个节点的实际行数、耗时与循环次数;再加 BUFFERS 会输出共享缓存命中与磁盘读取的块数。这三个选项组合起来,就能判断慢在计算、慢在 IO,还是估算偏差导致选错了连接方式。

基本信息

基本用法EXPLAIN (ANALYZE, BUFFERS) SELECT …
TIMING默认开启逐节点计时,设为 off 可减少测量开销
actual time首行到末行的实测耗时,单位毫秒
rows 与 loops每次循环的平均行数,总行数等于 rows 乘 loops
BUFFERSshared hit 是内存命中,read 是从磁盘读的块数
写语句实测放进事务执行后 ROLLBACK

实测输出示例

实测输出示例
EXPLAIN (ANALYZE, BUFFERS, TIMING)
SELECT o.id, o.total
FROM orders o
WHERE o.user_id = 100;

-- 输出示例:
-- Index Scan using idx_orders_user on orders o
--   (actual time=0.05..0.30 rows=12 loops=1)
--   Index Cond: (user_id = 100)
--   Buffers: shared hit=5 read=2
-- Planning Time: 0.3 ms
-- Execution Time: 0.5 ms

写语句安全实测

写语句安全实测
BEGIN;
EXPLAIN (ANALYZE) UPDATE orders SET status = 'x' WHERE id = 1;
ROLLBACK;   -- 实测完立刻回滚,避免真的改了数据

-- 只关心计划形态时,用不带 ANALYZE 的 EXPLAIN 即可,不会执行语句
EXPLAIN UPDATE orders SET status = 'x' WHERE id = 1;

关键字段读法

字段含义怎么用
actual time首行..末行耗时(毫秒)找出耗时占比最高的节点
rows 与 loops每次循环平均行数总读取量要乘 loops
Buffers: shared hit命中共享内存的块数命中高说明数据基本在缓存里
Buffers: read从磁盘读取的块数持续大量 read 说明缓存不足
Planning / Execution Time计划耗时与执行耗时判断计划本身是否也偏慢

典型使用场景

  • 确认索引是否被使用,或者退化成了顺序扫描
  • 判断慢在 IO 还是慢在计算:结合 Buffers 与 actual time
  • 排查连接方式:嵌套循环、哈希连接、归并连接哪个被选中
  • 验证统计信息准确性:对比估算行数与实际行数
  • 上线前用真实数据量验证执行计划
  • 评估写语句的计划:事务内执行后回滚
TIMING off 会关闭逐节点计时,只保留汇总的 Planning Time 与 Execution Time:节点多、调用频繁时能明显减少测量开销,适合只看整体耗时而不需要定位到具体节点的时候。
ANALYZE 会真正执行语句:写操作必须在事务里执行后回滚,并避开业务高峰;重查询同样消耗真实资源,先在预发库或从库上验证。

易错点

  • 对写语句直接 ANALYZE:会真实修改数据并持有锁,务必放进事务并回滚
  • 忽略 loops 直接看 rows:嵌套循环内层的 rows 是单次循环值,不乘 loops 会低估扫描量
  • 只看 Execution Time 不看 Buffers:无法区分是计算慢还是磁盘慢,优化方向容易选错
  • 把首次执行的结果当常态:缓存未预热时 read 偏高,多执行几次再看 Buffers 更准确

数据来源与参考

  • PostgreSQL Documentation §14.1 Using EXPLAIN
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌