Version Count 数目过多诊断的方法
1、关于 version count
首先我们一起来回顾一下 Oracle 的 父子游标
(child cursor and parent cursor)概念。在 Oracle 中,任何一个执行的 SQL 语句,都会以游标 cursor 的形式进行处理。具体来说,一个 SQL 要涉及到两个游标对象,共享游标 shared cursor 和私有游标 private cursor。
Private cursor 是驻留在 Oracle Server Process PGA 内部,只能被一个 Server Process 对应的会话使用。而 shared cursor 驻留在 SGA 的 shared pool 中,具体位于 shared pool 中的 library cache。
对 shared cursor 而言,主要缓存的目的在于执行计划的共享。一个 SQL 经过 validate 和 parse 过程,会形成父游标和子游标的配对组合。SQL 文本完全相同的语句,会共享父游标。而环境信息、对象信息相同的 SQL 语句,才可能共享子游标。当找不到对应的子游标或者父游标时,也就意味着找不到可共享的执行计划。这样对应的 SQL 就需要发生 hard parse,重新生成执行计划。
一个父游标下对应的子游标个数,我们成为 version count
。每一个子游标对应一个执行计划对象。
version count 就表示当前父游标下对应子游标的个数。如果一个父游标对应的子游标 version count 过多,也就是对应了很多的子游标对象。这样,当 server process 检查可共享的游标时,就需要长时间的检索子游标列表。
最有名的 version count 过多问题是由于设置 cursor_sharing
参数为 similar 后,引发的 version count 错误。此外,version count 过多也是我们需要诊断 SQL 为什么不会共享的一个出发点。比较常用的有两种,本篇中进行详细介绍。
2、v$sql_shared_cursor 视图
SQL 执行计划的生成,是受到很多因素影响的。相同父游标只是表示输入 SQL 的字面值相同。子游标对应的因素,如优化器类型、optimizer_mode、对应对象权限等的差异,都会影响到子游标的共享。
在 Oracle 11g 中,一个新的视图被提供出来,用于帮助诊断子游标不共享问题的原因,就是 v$sql_shared_cursor。该视图是一个宽列视图,通过 sql_id 和 child_number 就可以定义某个特定子游标的信息。其他大部分列都是以 varchar2(1) 的 Y/N 取值,每列的含义都是一个不能共享的理由。注意:这个理由 N 表示的是不能共享第一个子游标 child_number=0 的理由。
3、version-rpt 脚本
在 MOS438755.1 中,Oracle 提供了一个专门的脚本程序,用于协助诊断 high SQL version count 问题。
首先,我们需要从 MOS 上下载到脚本 version_rpt.sql
,目前笔者的版本为 3.1.2。使用 sys 用户登录之后,调用该脚本创建相应的数据库对象。
4、结论
version count 问题是 Oracle SQL 共享的一个方面。借助适当的工具手段,我们可以准确的定位问题,解决问题。
如果我们修改了优化器参数、环境变量、绑定变量等,都可能使得 SQL 发生重新解析,产生不同的子游标,也就是不同的 VERSION
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论