由 John Doe 三月 2, 2026
pg_stat_statements 是 PostgreSQL 生态中最核心、使用最广泛的 SQL 性能监控扩展,它能持久化记录数据库中所有 SQL 语句的执行次数、耗时、IO 开销等核心指标,是 DBA 定位慢查询、优化数据库性能的必备工具。但长期以来,它存在一个能力缺口:无法跟踪 SQL 语句的计划生成开销。

特性提交日志
pg_stat_statements:新增通用计划与自定义计划计数器。
此补丁为 pg_stat_statements 新增了两个计数器:
- generic_plan_calls(通用计划调用次数)
- custom_plan_calls(自定义计划调用次数)
这两个计数器分别用于跟踪预编译语句(prepared statement)使用通用计划(generic plan)和自定义计划(custom plan)执行的次数。pg_prepared_statements 的数据仅局限于单个会话,而新增计数器则在查询级别(涵盖顶层和非顶层查询)提供了与 pg_prepared_statements 功能等效的全局统计数据。
讨论:https://postgr.es/m/CAA5RZ0uFw8Y9GCFvafhC=OA8NnMqVZyzXPfv_EePOt+iv1T-qQ@mail.gmail.com
示例
假设我们需要评估系统的计划缓存效率:哪些 SQL 适合复用通用计划降低 CPU 开销,哪些 SQL 必须使用自定义计划保障执行性能,避免出现 “CPU 优化过度导致执行性能下降” 或 “重复优化导致 CPU 占用过高” 的问题。
下面我们就来使用该新特性,优化 OLTP 系统的计划缓存效率。
统计通用计划占比高于 99% 的高频 SQL:
SELECT
queryid,
LEFT(query, 80) AS query_preview,
calls,
-- 计算通用计划占比
generic_plan_calls::NUMERIC / calls AS generic_plan_ratio,
mean_exec_time
FROM pg_stat_statements
WHERE calls > 1000
AND generic_plan_ratio > 0.99
ORDER BY calls DESC;
统计自定义计划占比高于 99%、计划生成开销高的高频 SQL:
SELECT
queryid,
LEFT(query, 80) AS query_preview,
calls,
-- 计算自定义计划占比
custom_plan_calls::NUMERIC / calls AS custom_plan_ratio,
mean_exec_time,
mean_plan_time
FROM pg_stat_statements
WHERE calls > 1000
AND custom_plan_ratio > 0.99
ORDER BY total_plan_time DESC;
分类优化策略:
- 通用计划占比高于 99%、执行耗时稳定的 SQL:无需调整,计划复用已有效降低 CPU 开销,符合 OLTP 优化目标。
- 自定义计划占比高于 99%、高频执行、计划生成耗时高的 SQL:评估是否可通过使用预备语句、存储过程,让优化器选择通用计划,减少重复生成计划的 CPU 开销。
- 两种计划混用的 SQL:结合业务场景通过
plan_cache_mode强制指定计划类型,避免计划切换带来的性能抖动。
非常不错的体验,感谢所有参与的社区人员。
参考
提交日志:https://git.postgresql.org/pg/commitdiff/3357471cf9f5e470dfed0c7919bcf31c7efaf2b9