分类: Oracle
2008-04-22 19:48:16
Oracle11g创建了新术语“SQL计划演变”来描述查找一套SQL语句的最佳执行计划的渐进过程,我在本系列的第一篇文章中提到过,无论何时,SPM为SMB中的SQL语句拦截一个新的执行计划,然后,SPM保存那个计划到SMB中将其作为SQL语句历史的一部分,然而,SPM不允许使用该计划除非它通过了性能评估,能提升性能。如果SPM判断该新计划可以提升性能,SPM将改变该计划的状态为ACCEPTED,这个概念与计划进展一样著名,在SMB中的SQL语句自动演变是SPM的核心。
为了说明这个概念,我创建了一个简单的SQL语句(SPM_3_1.SQL)查询在销售历史(SH)方案中的几个表,要创建一个干净的状态SPM会评估这个查询,无论如何,我首先将从标记有注释字符串SPM_的SMB、库缓存和数据库缓存中清除SQL计划基线,如列表3.6显示的那样。一旦清除完成,我将在会话层使用列表3.7中的代码设置初始化参数OPTIMIZER_CAPTURE_SQL_PLAN_BASELINE的值为FALSE将自动捕获SQL计划基线设置为非激活状态,执行查询,然后使用函数DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE手动从库缓存中捕获SQL计划基线的结果。
绑定值监视及适应性游标共享
我在SQL语句SPM_3_1.sql中故意使用了绑定变量以说明SQL计划管理如何与绑定变量交互,基本成本的优化器从Oracle9.0.1以来就已经可以利用这个特色了,它让CBO基于提供给绑定变量的第一套值判断出一个更准确的执行计划。
Oracle11g也引入了一个叫做适应性游标共享的新特性,它能非常高效地与绑定变量和共享游标进行交互,SPM会通过标记每捕获的第一个执行计划作为对应的SQL计划基线解决这两个特性之间的所有冲突,如果我重新执行了相同的查询但为绑定变量使用了不同的值,它相对原始计划性能可能更低了,要预防这个问题,SPM将存储这个执行计划作为SMB中SQL语句计划历史的一部分,但是新的计划不会被使用除非SPM校验了它,并认为它效率更高。(我会在以后的文章中专门讲述这一方面的内容,并讲述适应性游标共享如何工作)
请求SQL计划基线演变
换句话说,当SPM检测到一个性能更好的计划会发生什么?我将在SH.CUSTOMERS表中的CUST_LAST_NAME列上添加一个索引来模拟这个情景,这个索引对于SQL语句SPM_3_1.sql的性能将起到立竿见影的影响,因为不再会在SH.CUSTOMERS上请求一个全表扫描了。一旦我在会话层将初始化参数OPTIMIZER_CAPTURE_SQL_PLAN_BASELINE的值设置为默认值(TRUE)以重新激活自动捕获SQL计划基线的话,我将再次执行该SQL语句并校验捕获的SQL计划基线的结果,CBO将收集一个新的会使用到该新索引的执行计划,来提升语句的性能,新的执行计划也将记录到SMB中(查看列表3.8)
直到SPM演变这个新的计划,否则,这个计划不会通过语句的SQL计划基线被利用,当我执行函数DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE时,Oracle 11g 将立即评估所有可用的SQL计划基线并性能得到提升的计划,这个函数返回一个CLOB类型的值,它列出了所有状态被修改为ACCEPTED的SQL计划基线,我在列表3.9值展示了这个计划演变的结果,为了说明无论何时执行这条sql语句时该SQL计划基线都将被使用到,我对该语句运行了一个执行计划并使用+NOTES指令格式化输出结果。
通过SQL调整顾问自动演变计划
Oracle 11g 也提供了SQL计划基线的自动演变,通过对每个选择的SQL语句执行SQL调整顾问程序实现,因为自动SQL调整(AST)批处理过程在每天夜间规律地执行时也会请求SQL调整顾问,AST也可以接受SQL配置文件,无论何时,配置文件能比当前的SQL计划基线提供更好的性能。(要查看更多关于自动SQL调整的信息,请查看这篇文章)