登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
导读
排行榜
资讯
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
写博客
小组
VIP申请
VIP网盘
网盘
联系我们
发帖说明
道具
勋章
任务
淘帖
动态
分享
留言板
导读
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
安全
›
为什么PostgreSQL不自动缓存执行计划?这可能是最硬核的 ...
为什么PostgreSQL不自动缓存执行计划?这可能是最硬核的优化解读
[ 复制链接 ]
锷稠
2025-9-25 21:11:07
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
为什么PostgreSQL不自动缓存执行计划?这可能是最硬核的优化解读
前言
在数据库性能方面,查询语句的执行计划是最关键的因素之一。每当数据库接收到一个查询时,它必须决定如何以最有效的方式执行该查询。这个决策过程——称为
执行计划
。 计算并生成最优的执行计划在时间上可能非常昂贵,尤其是对于经常执行的查询语句。为了减轻这种开销,数据库采用
执行计划缓存
(Oracle和SQL Server都会自动缓存执行计划)来解决这个问题,使它们能够重用先前计算的执行策略,而不是每次执行时都重新计算执行计划。
然而,执行计划缓存的工作方式在不同的数据库系统之间可能存在显著差异。PostgreSQL 对执行计划缓存采用了一种更加动态和自适应的方法,而 SQL Server 默认则会积极缓存所有语句的执行计划,从而导致性能上的巨大差异。
这里会深入探讨 PostgreSQL 如何处理执行计划缓存,并将它与 SQL Server 进行比较,以及如何在针对这两个数据库进行性能优化。然后还将讨论预处理语句、函数缓存、通用与自定义执行计划,以及两个数据库中的常见性能陷阱。
PostgreSQL 如何缓存执行计划
PostgreSQL 并不会自动缓存SQL 语句的执行计划。每次执行SQL 查询(如 SELECT、INSERT、UPDATE 或 DELETE)时,PostgreSQL 都会从头开始解析、优化生成执行计划并执行该查询。
这一行为与 SQL Server 大相径庭,但是后者默认会全局缓存执行计划。虽然这看起来一开始是一个劣势,但实际上,这使得 PostgreSQL 在数据分布随时间变化的动态环境中能够做出更好的执行计划优化决策。然而,PostgreSQL 确实会在某些情况下缓存执行计划,包括prepare预处理语句和 PL/pgSQL 函数。
预处理语句和查询计划缓存
在 PostgreSQL 中如果要使用执行计划缓存,可以使用预处理语句。预处理语句允许 PostgreSQL 缓存查询的执行计划,这样每次执行查询时就不需要重新编译它。
PREPARE get_users (INT) AS
SELECT * FROM users WHERE age > $1;
EXECUTE get_users(30);
复制代码
在上面例子中:
第一次调用 PREPARE 语句时,PostgreSQL 解析并规划查询。
当 EXECUTE 执行时,会重用缓存的执行计划,从而避免了额外的解析和规划开销。
自定义执行计划 vs. 通用执行计划
默认情况下,PostgreSQL 从自定义执行计划开始——该执行计划针对特定的参数值进行了优化。然而,如果一个prepare预处理语句被多次执行(通常是5次或更多次),PostgreSQL 会评估是否应该切换到通用执行计划。自定义执行计划是根据实际的参数值进行优化的,并且可能使用索引扫描、顺序扫描或其他优化的执行路径,这取决于数据的分布情况。
另一方面,通用执行计划是没有特定参数值的,而是依赖于来自 pg_statistic 的表统计信息来估算行的基数/选择性。这种方法消除了每次执行时的执行计划生成开销,但如果数据分布不均匀(数据倾斜),可能会导致查询使用的执行计划不佳。
PL/pgSQL 函数和执行计划缓存
PostgreSQL 还会在 PL/pgSQL 函数中缓存执行计划。当函数包含SQL语句时,PostgreSQL 在第一次执行后会缓存执行计划。
CREATE FUNCTION get_users_by_age(age_limit INT)
RETURNS SETOF users AS $$
BEGIN
RETURN QUERY SELECT * FROM users WHERE age > age_limit;
END;
$$ LANGUAGE plpgsql;
复制代码
第一次运行该函数时,PostgreSQL 会为 SELECT 语句创建一个缓存的执行计划。如果该函数被频繁调用,PostgreSQL 可能会像处理预处理语句一样切换到通用执行计划。为了控制这一行为,PostgreSQL 允许开发人员手动强制指定缓存策略:
ALTER FUNCTION get_users_by_age SET plan_cache_mode = 'force_custom_plan';
ALTER FUNCTION get_users_by_age SET plan_cache_mode = 'force_generic_plan';
复制代码
理解索引下的执行计划行为
PostgreSQL 决定使用自定义执行计划还是通用执行计划的一个主要因素是索引选择性。如果某个字段具有高基数(有很多唯一值),通常使用索引扫描是最佳选择。然而,如果某个字段具有低基数(唯一值较少),顺序扫描可能更高效。例如,考虑以下情况:
CREATE INDEX idx_users_age ON users(age);
复制代码
如果大多数年龄值分布均匀,PostgreSQL 可能更倾向于使用通用执行计划,因为参数变化对执行时间的影响不大。然而,如果某些值出现频率较高(例如:年龄 = 25 占据了表 60% 的行数),使用自定义执行计划将更有效。
总结
理解执行计划缓存的工作原理对于数据库性能调优至关重要。PostgreSQL 采取动态方法,避免了
参数嗅探
的陷阱,但需要明确配置以实现执行计划的重用。另一方面,SQL Server 激进地缓存执行计划,这可以减少每次执行计划生成的开销,但当参数值变化较大时,可能会引发
参数嗅探
问题。
对于从 SQL Server 转向 PostgreSQL 的开发人员,适应 PostgreSQL 的执行计划缓存行为可能需要一些时间。然而,通过谨慎使用prepare预处理语句、函数和
plan_cache_mode
参数设置,开发人员可以精细调优 PostgreSQL,以实现最佳性能。
本文版权归作者所有,未经作者同意不得转载。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
为什么
PostgreSQL
自动
缓存
执行
相关帖子
C++性能优化必知:CPU缓存与伪共享避免实战指南
自动跳转的js代码
html自动跳转代码合集
考陪诊师为什么选北京守嘉陪诊报名?
考陪诊师为什么选北京守嘉陪诊报名?
考陪诊师为什么选北京守嘉陪诊报名?
为什么关注 CE 认证 + 特变电工供应商?
大疆不同任务类型执行逻辑,上云API源码分析
扣子Coze实战:智能体(Agent)1分钟自动仿写公众号爆文,一键自动发布
postgreSQL 中的自定义操作符
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
安全
C++性能优化必知:CPU缓存与伪共享避免实战指南
0
471
煅圆吧
2025-12-11
代码
自动跳转的js代码
0
12
新程序
2025-12-11
代码
html自动跳转代码合集
0
14
新程序
2025-12-11
安全
考陪诊师为什么选北京守嘉陪诊报名?
0
136
唐茗
2025-12-12
安全
考陪诊师为什么选北京守嘉陪诊报名?
0
905
陶田田
2025-12-12
安全
考陪诊师为什么选北京守嘉陪诊报名?
1
651
滕佩杉
2025-12-12
安全
为什么关注 CE 认证 + 特变电工供应商?
0
735
康器
2025-12-12
业界
大疆不同任务类型执行逻辑,上云API源码分析
0
53
迭婵椟
2025-12-12
业界
扣子Coze实战:智能体(Agent)1分钟自动仿写公众号爆文,一键自动发布
0
1
高小雨
2025-12-13
业界
postgreSQL 中的自定义操作符
0
810
蔺堰
2025-12-13
回复
(4)
后彼
2025-10-25 01:13:23
回复
使用道具
举报
照妖镜
程序园永久vip申请,500美金$,无限下载程序园所有程序/软件/数据/等
热心回复!
揭荸
2025-11-26 20:11:13
回复
使用道具
举报
照妖镜
程序园永久vip申请,500美金$,无限下载程序园所有程序/软件/数据/等
不错,里面软件多更新就更好了
郏琼芳
2025-11-28 15:00:40
回复
使用道具
举报
照妖镜
程序园永久vip申请,500美金$,无限下载程序园所有程序/软件/数据/等
这个有用。
诘琅
前天 14:33
回复
使用道具
举报
照妖镜
程序园永久vip申请,500美金$,无限下载程序园所有程序/软件/数据/等
这个有用。
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
签约作者
程序园优秀签约作者
发帖
锷稠
前天 14:33
关注
0
粉丝关注
16
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
anyue1937
9994893
kk14977
6845356
3934307807
991123
4
xiangqian
638210
5
韶又彤
9999
6
宋子
9983
7
闰咄阅
9993
8
刎唇
9993
9
俞瑛瑶
9998
10
蓬森莉
9951
查看更多
今日好文热榜
631
玩转 | q群智能聊天机器人 —— MaiBot(麦
988
offline meta-RL | 近期工作速读记录
658
C#AI系列(5): C#离线实现高效OCR
192
这才是vibe coding正确的打开方式 - 手把手
543
huggingface_hub 1.0 正式版现已发布:开源
831
嵌入式系统内存魔法之分散加载
743
嵌入式系统内存魔法之分散加载
127
【Java】ThreadLocal源码解析
29
观察者模式,发布/订阅模式,与回调函数
698
用 GPT-5.2 Vibe Coding,做了一个可以“玩
935
上海专业防水补漏服务:国家一级资质,免费
355
基于深度学习的无人机视角检测系统演示与介
768
读书笔记 XILINX ug1137-Zynq UltraScale+
127
DBeaver 与 Excel JDBC 驱动(xlSql)使用说
931
【节点】[Adjustment-InvertColors节点]原
720
笔记 XILINX ug1085-Zynq UltraScale+ Devi
451
笔记 XILINX ug1085-Zynq UltraScale+ Devi
725
读书笔记 XILINX ug1085-Zynq UltraScale+
902
基于深度学习的船舶检测系统演示与介绍
442
吴恩达深度学习课程四:计算机视觉