Oracle 11g 新特性--自适应游标共享(1)
正如我过去做老师时告诉学生的那样,我有一个好方法可以避免数据库性能降低,说来也很简单,就是要求应用程序开发人员不要在数据库运行任何SQL语句,但这的确引来不少人的笑声和嘲笑,还是回到现实中来吧,讨论一下建立有效SQL语句的途径,我认为没有什么标准可供借鉴,但构造不佳的SQL语句迟早会导致联机事务处理(OLTP)系统、决策支持系统(DSS)或混合数据库表现不佳。
“偷窥”绑定变量:这不是作弊
幸运的是,Oracle数据库为我们提供了一些很好的工具,用以确定需要改善性能的SQL语句,并为提升它们的性能提供建议,这个方法的核心是当确实需要一个新的执行计划时,我们可以修改基于成本的SQL优化器解析SQL语句的方式。当然,当一条语句第一次执行时必须硬解析,这样优化器可以确定获取所需数据的最佳路径,因为解析是一个相对费时的操作,因此,DBA通常会限制存储在库缓存中的唯一性游标的数量,特别是在联机事务处理环境下,相同的语句可能会被执行成百上千次,它们为用户会话返回相似的结果集。
设置有效的游标共享最简单的方法就是按照应用程序工作量的需要为CURSOR_SHARING初始化参数设定合适的值,将这个参数的值设为SIMILAR告诉优化器当SQL语句完全相同,除了谓词部分外,可以使用游标共享,执行计划提供相等或更优的性能,同样,将其值设为CURSOR_SHARING时,不论是否存在更好的执行计划,告诉优化器强制共享游标,当SQL语句包含绑定变量时,有极好的机会提供这方面的性能优势,但当优化器在不知道是什么值来填充产生的游标时,怎样才能构建一个有效的执行计划呢?
早在Oracle 9i就进行了一些尝试,为了克服可能出现的非最佳的执行计划,引入了绑定变量偷窥,顾名思义,当一个包含绑定变量的SQL语句首次执行时,Oracle会快速查看这些绑定变量的一个真实值,以便构建一个最佳的执行计划,这个方法的优点很明显:不再是猜测最佳的执行计划了,因为那样产生的执行计划可能并不是最佳的,基于成本的优化器使用真实的值来构建执行计划。
但不幸的是,这个方法对于非OLTP系统的缺点也很明显,例如,如果决策支持系统下次运行的查询指定了一套绑定变量的值,那此时要想高效地执行查询,需要一个完全不同的执行计划吗?实际上,这种数据仓库环境并不罕见,对于决策支持系统,它可能非常希望有多个可用的执行计划作为候选,因为一个绑定变量集可能返回的结果集只包含几百行的数据,而另一套绑定变量可能返回几百万行数据,因此,Oracle建议保留CURSOR_SHARING作为该初始化参数的默认值,以强制产生一个新的更有效的执行计划。
自适应游标共享:更灵活的绑定
Oracle 11g提供自适应游标共享(ACS)以克服不该共享时的游标共享,ACS使用了两个新的度量机制:绑定敏感度和绑定感知。
绑定敏感度:无论何时,当包含绑定变量的SQL语句首次执行时,优化器在偷窥了绑定变量的值后,会为其标记一个绑定敏感度,以确定语句的谓词,但偷窥结束时也类似,因为它也为后面相同语句相同绑定变量不同值时进行对比,以确定是否要产生新的执行计划。
为了说明这些绑定敏感度是如何工作的,我在Oracle 11g的SH示例方案中的SH.SALES表上构造了一个简单的查询,因为它是方案中最大的表了,并且也按时间范围进行分区,如列表1所示:
列表1:



