分类: Oracle
2008-04-22 19:45:19
每当我部署一个新的应用程序到我的生产数据库时,我知道我实际上受应用程序开发人员和质量保证人员的摆布,即使我坚决主张严谨的数据库对象命名标准,严格坚持PL/SQL最佳实践,给不同绑定变量使用不同的值对SQL语句进行广泛地测试,我也知道这些指导意见往往不切实际。当我商店的应用程序开发团队和QA资源不能达成一致的标准时,或如果我的IT管理上司认为我们花费了太多时间进行测试,我知道这是一个新开发的内部应用程序对调整好的Oracle数据库施加严重的性能影响的好机会。
另一个可能引起数据库性能下降的因素是那些经过管理层批准强制部署的第三方应用程序,每个经验丰富的Oracle DBA有至少遇到过一次这种情况:一个外部应用程序正引起严重的性能问题,经过调查显示该应用程序的开发人员使用了“agnostic SQL”以满足在任何操作系统环境中的任何数据库上都能运行该应用程序,结果是,SQL代码不能直接调整,因为它是放置在应用程序中的。
好消息是当部署一个崭新的应用程序到下列环境中时,Oracle 11g提供了一些避免降低性能的希望:
◆对于一个内部应用程序,我只需要捕获应用程序最典型的SQL语句到SQL调整集进入QA环境进行评估
◆对于一个第三方应用程序,在应用程序部署之前,我可以要求厂商就所有SQL语句发送给我,因此我可以预先捕获并评估它们的性能,或者:当它在一个QA或开发环境中执行时,我直接从库缓存中捕获它最常用的SQL语句。
一旦我捕获了新应用程序的SQL语句,我就可以使用现有的QA或开发数据库捕获它们对应的SQL计划基线,然后直接转移那些基线进入生产数据库的SMB中,最终结果如何呢?当应用程序最终部署好后这些执行计划早已经准备好了,因此,在首次部署到生产环境中时,可以让CBO不再为这些忙碌的SQL语句建立执行计划了,最好的情况是,如果最佳执行计划提升了这些SQL语句的性能,CBO将自动演变这些改进多的计划。
准备模拟
在我模拟这个情景之前,我执行了一些配置任务,我在列表2.5中将它们集中起来了:
◆首先我用存储过程DBMS_SPM.DROP_SQL_PLAN_BASELINE清除了我当前的Oracle 11g数据库SMB中的SQL计划基线。这个存储过程接受“SQL句柄”(SQL handle)和“计划名字”(plan name)作为参数,然后从SMB中移除对应的SQL计划基线,我编写了一个无名的PL/SQL块,它利用一个游标捕获所有的SQL计划基线,游标的SQL文本包括了一个类素SPM_2的注释,然后反回对应的SQL句柄/计划名字组合给存储过程,这个方法允许细粒度的控制SMB中的内容,我将贯穿这些情景多次使用它,当必要时有选择性地减少SMB的粒子数。
◆然后我会构造组成销售人员管理系统的基本组件,如在SFA_Setup.sql中显示的内容,我就创建一个新的方案所有者(SFA),授予它适当的系统和对象权限,最后在该方案中创建并填充几个表。
捕获SQL计划基线
在列表2.6中我说明了对这个新应用程序捕获一个模拟的SQL工作负载的步骤:
◆为了在测试环境中模拟捕获一个简单的工作负载测试,在执行SPM_2_2.sql中的代码之前,首先我会保证当前的Oracle 11g数据库库缓存和数据库缓存是清空的,有六个查询 -- 所有查询都被用(SPM_2_2)加以注释以便识别 -- 展示了几个不同的用途,用户可能决定在区域、地区和领域层联合新应用程序SFA方案中关于我的销售人员和销售历史方案(SH)中的销售历史信息,注意我在这些查询中也使用了大量的绑定变量,因此我有机会在将来的示例中评估其他的执行计划。
◆一旦工作负载被生成,这六个查询也被解析到Oracle 11g数据库的库缓存中,通过函数DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE捕获它们的SQL计划基线进入SMB中就相对简单了,这个函数的过滤功能允许我只捕获那些有SPM_2_2注释信息的SQL语句。