排行
数据库百科
核心案例
行业报告
月度解读
大事记
产业图谱
中国数据库
向量数据库
时序数据库
实时数据库
搜索引擎
空间数据库
图数据库
数据仓库
大调查
2021年报告
2022年报告
年度数据库
2020年openGauss
2021年TiDB
2022年PolarDB
2023年OceanBase
首页
资讯
活动
大会
学习
课程中心
推荐优质内容、热门课程
学习路径
预设学习计划、达成学习目标
知识图谱
综合了解技术体系知识点
课程库
快速筛选、搜索相关课程
视频学习
专业视频分享技术知识
电子文档
快速搜索阅览技术文档
文档
问答
服务
智能助手小墨
关于数据库相关的问题,您都可以问我
数据库巡检平台
脚本采集百余项,在线智能分析总结
SQLRUN
在线数据库即时SQL运行平台
数据库实训平台
实操环境、开箱即用、一键连接
数据库管理服务
汇聚顶级数据库专家,具备多数据库运维能力
数据库百科
核心案例
行业报告
月度解读
大事记
产业图谱
我的订单
登录后可立即获得以下权益
免费培训课程
收藏优质文章
疑难问题解答
下载专业文档
签到免费抽奖
提升成长等级
立即登录
登录
注册
登录
注册
首页
资讯
活动
大会
课程
文档
排行
问答
我的订单
首页
专家团队
智能助手
在线工具
SQLRUN
在线数据库即时SQL运行平台
数据库在线实训平台
实操环境、开箱即用、一键连接
AWR分析
上传AWR报告,查看分析结果
SQL格式化
快速格式化绝大多数SQL语句
SQL审核
审核编写规范,提升执行效率
PLSQL解密
解密超4000字符的PL/SQL语句
OraC函数
查询Oracle C 函数的详细描述
智能助手小墨
关于数据库相关的问题,您都可以问我
精选案例
新闻资讯
云市场
登录后可立即获得以下权益
免费培训课程
收藏优质文章
疑难问题解答
下载专业文档
签到免费抽奖
提升成长等级
立即登录
登录
注册
登录
注册
首页
专家团队
智能助手
精选案例
新闻资讯
云市场
微信扫码
复制链接
新浪微博
分享数说
采集到收藏夹
分享到数说
首页
/
PostgreSQL的CURSOR SHARING
PostgreSQL的CURSOR SHARING
白鳝的洞穴
2021-06-26
1330
Oracle DBA最怕遇到CURSOR 相关的问题,如果发生了CURSOR争用导致的性能问题,是很难在短时间内分析清楚的。有时候我们重启数据库就解决了这个问题,不过有时候重启数据库后问题依然存在。幸运的是在PostgreSQL数据库中好像很少会遇到类似的问题,这是什么原因呢?
在一个高并发的系统中,SQL执行过程需要对SQL进行编译,这个过程无论哪种数据库都是必须有的。大体上分为语法语义解析、SQL REWRITE优化、执行计划生成、执行计划选择、执行等过程。在PostgreSQL中,可以用下面这个图来表示。
为了避免每次SQL执行之前都做上述昂贵的操作,Oracle构建了全局共享的CURSOR结构,用于在共享内存(SHARED POOL)中存储CURSOR共享部分的数据,用于所有的会话共享。似乎现在的Mysql、PostgreSQL等开源数据库和一些国产数据库都没有再采用这种全局共享CURSOR的机制,而大多数采用SQL不共享或者会话内共享CURSOR的机制,比如比较新版本的PostgreSQL就是采用会话内共享SQL的机制。
为什么Oracle使用全局CURSOR共享机制而PostgreSQL不使用呢?这实际上有两方面的原因,一个是历史原因,一个是商业原因。CURSOR共享在CPU资源不是很充裕的时代是相当有效提升RDBMS执行效率的手段,因为SQL解析是十分高开销的工作,能够一次编译多次执行,可以大大提高系统的并发执行性能。因此作为商用数据库的Oracle一直把提升CURSOR共享能力作为其核心竞争力,ORACLE的CURSOR全局共享就做成了一个独步天下的技术了。Postgresql这样的开源数据库没有Oracle的大手笔,因此选择了较为稳妥的会话内共享SQL的技术路线。幸亏是现在X86服务器技术的高速发展,CPU资源已经不是很难买到的了,因此不能在全局共享CURSOR的问题也已经不是一个特别严重的问题了。实际上,这些年我们遇到的因为CUSOR硬解析导致的ORACLE数据库性能问题也少了很多,主要原因是哪怕CURSOR解析使用了10+%的CPU资源,对我们的服务器来说也还是撑得住的。
虽然说PG并没有采用全局共享CURSOR的策略,不过在会话内共享多次执行的CURSOR仍然对PG数据库并发执行性能的提升有极大帮助的。说起共享CURSOR就不可避免地会聊到绑定变量的使用问题。使用绑定变量的好处是让SQL可以共享,可以让一条类似的SQL在多次执行中共享查询执行计划,这样就不需要每次都编译SQL语句;不过使用绑定变了也有缺点,在Oracle存在的著名的bind peeking问题在任何数据库中都会存在,因为绑定变量的差异可能选择不同执行计划才好的问题在很多时候都是存在的。在Oracle 9iR2之前,所有执行计划都是在变量绑定之前完成的,从9.2开始,Oracle将执行计划的生成放到了变量绑定之后,这样就让执行计划的生成更为精准了,不过这也带来了另外一个问题,那就是SQL第一次执行时的变量成为生成执行计划的依据,因此CURSOR共享会导致存在多种最优执行计划的SQL语句的运行性能变得不稳定。Oracle 11g之后的自适应CURSOR共享才基本上解决了这个问题。
PostgreSQL数据库的CURSOR共享机制学习了Oracle的这一个新的特性,采用了一种类似的方法来解决这个即共享CURSOR又尽可能避免多种最优执行计划导致的SQL性能问题,当然前提是,PostgreSQL的CURSOR共享是会话级的,不是实例级的。
在PostgreSQL的一个会话中,一条SQL的前五次执行,每次都会重新生成执行计划,这样就可以避免因为绑定变量的差异导致存在多种最优执行计划的问题无法被发现的问题出现。如果前五次编译发现存在通用执行计划,那么这个通用执行计划就会被共享。我们来看下面的例子。
我们可以看到,在前面五次执行的时候object_id都是代入具体得值的,而第六次执行就变成$1,这就是使用了通用执行计划。我们再来看一个复杂一些的例子。
从这个例子上可以看到,如果绑定变量出现了较大的差异,那么PostgreSQL不会一味的用通用执行计划去套用,而是会使用custom执行计划,通过全表扫描来替代索引扫描,从而确保SQL的高效执行,这和Oracle的Adaptive Cursor sharing的思路基本上是一致的。
postgresql
文章转载自
白鳝的洞穴
,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
领墨值
有奖问卷
意见反馈
客服小墨