PostgreSQL 19 - 新增generic_plan和custom_plan计数器
PostgreSQL 19 preview - pg_stat_statements新增generic_plan和custom_plan计数器
https://github.com/postgres/postgres/commit/3357471cf9f5e470dfed0c7919bcf31c7efaf2b9
本次 Commit(3357471cf9f5e470dfed0c7919bcf31c7efaf2b9)为 PostgreSQL 的 pg_stat_statements 插件增加了两个新统计字段:
generic_plan_calls custom_plan_calls
1. 为什么需要这个 Feature?
在 PostgreSQL 中,执行带参数的 SQL 语句时,可能会选择“通用计划(Generic Plan)”或“定制计划(Custom Plan)”。通用计划通常适用于参数变化较大、每次执行都能复用同一个执行计划的场景;定制计划则根据每次传入的参数单独生成,适合参数对执行路径影响很大的情况。
此前,pg_stat_statements 只能统计 SQL 被执行的次数、耗时等信息,无法区分到底是走了多少次通用计划、多少次定制计划。
引入这两个新字段,可以:
更精细地了解 SQL 执行计划的使用情况。 辅助性能分析,比如定位为何某些 SQL 总是用 Custom Plan 导致计划生成耗时高,或者反之。
2. 能排查什么问题?
排查计划缓存问题:如果某些 SQL 总是只用 custom_plan_calls,说明计划无法复用,有可能因为绑定参数类型、schema 变化、或者 planner cost 评估不恰当。 性能瓶颈定位:频繁的 custom plan 会带来较高的规划开销。通过统计,可以发现哪些 SQL 语句因为 custom plan 生成太多,导致整体响应变慢。可能是数据非常倾斜导致的问题, 先使用了罕见值, 形成了初期的custom plan avg cost. 未来在使用高频值时算出generic plan cost大于custom cost, 最终导致持续走custom plan. 非常容易模拟. 调优建议:发现 custom_plan_calls 明显多于 generic_plan_calls 时,可以考虑调整 SQL 写法、数据库参数(如 plan_cache_mode、校准项等),以提高计划复用率。
3. 示例
假设你有如下 SQL:
PREPARE my_stmt ASSELECT * FROM mytab WHEREid = $1;
SET plan_cache_mode TO force_generic_plan;
EXECUTE my_stmt(1); -- 走通用计划
SET plan_cache_mode TO force_custom_plan;
EXECUTE my_stmt(2); -- 走定制计划
你可以通过如下查询看到统计信息:
SELECTquery, calls, generic_plan_calls, custom_plan_calls
FROM pg_stat_statements
WHEREqueryLIKE'%mytab%';
可能返回:
这说明两次执行各用了一次不同的计划方式。
总结:该 feature 让 pg_stat_statements 更好地支持了 SQL 计划类型的细粒度分析,有助于数据库性能调优和问题排查,特别是在大规模应用和自动化 SQL 性能分析场景中非常有用。
更多细节可参考:commit 页面