文章转载自:http://blog.csdn.net/tianlesoftware/article/details/8292410
一.概述
SQL 语句的SQL 执行计划发生更改时,可能存在性能风险。
SQL 计划发生更改的原因有很多,如优化程序版本、优化程序统计信息、优化程序参数、方案定义、系统设计和SQL 概要文件创建等。
在以前版本的Oracle DB 中引入了各种计划控制技术(如存储的大纲(storedoutline(9i))和SQL 概要文件等(SQLprofile(10g))),用于解决计划更改导致的性能回归。但是,这些技术都是需要手动干预的被动式进程。
SQL 计划管理是一种随Oracle Database 11g 引入的新功能,通过维护所谓的“SQL 计划基线(SQL plan baseline(11g))”来使系统能够自动控制SQL 计划演变。启用此功能后,只要证明新生成的SQL 计划与SQL 计划基线相集成不会导致性能回归,就可以进行此项集成。因此,在执行某个SQL 语句时,只能使用对应的SQL 计划基线中包括的计划。可以使用SQL 优化集自动加载或植入SQL 计划基线。
SQL 计划管理功能的主要优点是系统性能稳定,不会出现计划回归。此外,该功能还可以节省DBA 的许多时间,这些时间通常花费在确定和分析SQL 性能回归以及寻找可用的解决方案上。
二.SQL 计划基线(Plan BaseLine):体系结构
SQL 计划管理(SPM) 功能引入了支持新计划的计划维护和性能验证所必需的基础结构和服务。
对于多次执行的SQL 语句,优化程序会为单个SQL 语句维护一个计划历史记录。优化程序通过维护语句日志来标识可重复的SQL 语句。如果对某个已记录的SQL 语句再次进行语法分析或再次执行该语句,则将该SQL 语句标识为可重复的语句。将某个SQL 语句标识为可重复之后,由优化程序生成的各种计划将作为包含相关信息(如SQL 文本、大纲、绑定变量和编译环境等)的计划历史记录得以维护;优化程序将使用这些信息来复制执行计划。
作为自动识别可重复SQL 语句及创建其计划历史记录的一种替代或补充,系统也支持为一系列SQL 语句手动植入计划。
计划历史记录包含优化程序在某段时间内为SQL 语句生成的不同计划。但是,只有计划历史记录中的部分计划可能被接受并得以使用。例如,正常情况下不会使用优化程序生成的新计划,除非该计划得到验证不会导致性能回归。在维护窗口中作为自动化任务运行自动SQL 优化时,就会自动完成计划验证。
自动SQL 优化任务的唯一目标是获得高负载的SQL 语句。为此,该任务会自动执行一些操作,例如,使成功的已验证计划成为已接受的计划。一系列可接受的计划组成了一个SQL 计划基线(plan baseline)。为一个SQL 语句生成的第一个计划很显然是可接受的计划,因此,该计划形成了原始的计划基线。优化程序后来发现的任何新计划都包含在计划历史记录中,但最初都不包含在计划基线中。
语句日志、计划历史记录和计划基线都存储在SQL 管理库(SMB) 中;该库还包含SQL概要文件。SMB 是数据库字典的一部分,存储在SYSAUX 表空间中。SMB 使用自动空间管理(例如,定期清除未使用的计划)。可以对SMB 进行配置,以更改计划保留策略和设置空间大小限制。
注:使用OracleDatabase 11g 时,如果数据库实例已启动,但SYSAUX 表空间为OFFLINE,则优化程序将无法访问SQL 管理对象。这可能会影响某些SQL 工作量的性能。
三. 加载SQL 计划基线
加载SQL 计划基线的方式有两种:
(1) 即时捕获:
使用自动计划捕获,方法是:将初始化参数OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES 设置为TRUE。默认情况下,该参数设置为FALSE。将该参数设置为TRUE 将打开自动标识可重复SQL 语句,以及自动为此类语句创建计划历史记录的功能。
(2) 成批加载:
使用DBMS_SPM 程序包;该程序包支持手动管理SQL 计划基线。使用此程序包,可以将SQL 计划从游标高速缓存或现有的SQL 优化集(STS) 直接加载到SQL计划基线中。对于要从STS 加载到SQL 计划基线的SQL 语句,需要将其SQL计划存储在STS中。使用DBMS_SPM 可以将基线计划的状态从已接受更改为未接受(以及从未接受更改为已接受),还可以从登台表导出基线计划,然后使用导出的基线计划将SQL 计划基线加载到其它数据库中。
四.演化SQL 计划基线
在SQL 计划基线演化阶段,Oracle DB 会按常规方式评估新计划的性能,并将性能较好的计划集成到SQL 计划基线中。
优化程序为SQL 语句找到新的计划时,会将该计划作为未接受的计划添加到计划历史记录中。然后,相对于SQL 计划基线的性能,验证该计划的性能。如果经验证某个未接受的计划不会导致性能回归(手动或自动),则该计划会被更改为已接受计划,并集成到SQL 计划基线中。成功验证未接受计划的过程包括:对此计划的性能和从SQL计划基线中选择的一个计划的性能进行比较,确保其性能更佳。
演化SQL 计划基线的方式有两种:
(1)使用DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE 函数。该函数将返回一个报表,显示是否已将一些现有的历史记录计划移到了计划基线中。也可以在历史记录中指定要测试的特定计划。
(2)运行SQL 优化指导:通过使用SQL 优化指导手动或自动优化SQL 语句,演化SQL计划基线。SQL优化指导发现已优化的计划,并确认其性能优于从相应的SQL 计划基线中选择的计划的性能时,就会生成一个建议案以接受SQL 概要文件。接受了该SQL 概要文件后,会将已优化的计划添加到相应的SQL 计划基线中。
五. 重要的基线SQL 计划属性
如果将计划添加到计划历史记录中,则该计划将与一些重要的属性关联:
(1)SIGNATURE、SQL_HANDLE、SQL_TEXT 和PLAN_NAME 是搜索操作的重要标识符。
(2)使用ORIGIN 可以确定计划是自动捕获的(AUTO-CAPTURE)、手动演化的(MANUALLOAD)、通过SQL 优化指导自动演化的(MANUAL-SQLTUNE) 还是通过自动SQL 优化自动演化的(AUTO-SQLTUNE)。
(3) ENABLED 和ACCEPTED:ENABLED属性表示计划已启用,可供优化程序使用。如果未设置ENABLED,则系统将不考虑此计划。ACCEPTED 属性表示用户在将计划更改为ACCEPTED 时计划已经过验证为有效计划(系统自动进行的或用户手动进行的)。如果将某个计划更改为ACCEPTED,则仅当使用DBMS_SPM.ALTER_SQL_PLAN_BASELINE()更改其状态时,该计划才是非ACCEPTED 的。可以通过删除ENABLED设置暂时禁用ACCEPTED 计划。计划必须为ENABLED 和ACCEPTED,优化程序才会考虑使用它。
(4) FIXED 表示优化程序仅考虑标记为FIXED 的计划,而不考虑其它计划。例如,如果有10 个基线计划,其中的三个计划被标记为FIXED,则优化程序将仅使用这三个计划中的最佳计划,而忽略其它所有计划。如果某个SQL 计划基线至少包含一个已启用的已修复计划,则该SQL 计划基线就是FIXED 的。如果在修复的SQL 计划基线中添加了新计划,则在手动将这些新计划声明为FIXED 之前,无法使用这些新计划。
可以使用DBA_SQL_PLAN_BASELINES视图查看每个计划的属性。然后,可以使用DBMS_SPM.ALTER_SQL_PLAN_BASELINE 函数更改其中的某些属性。也可以使用DBMS_SPM.DROP_SQL_PLAN_BASELINE 函数删除计划或整个计划历史记录。
注:DBA_SQL_PLAN_BASELINES 视图包含了一些附加属性;使用这些属性可以确定各个计划的上次使用时间,以及是否应自动清除某个计划。
六.SQL 计划选择
如果使用的是自动计划捕获,则第一次将某个SQL 语句标识为可重复时,其最佳成本计划将被添加到对应的SQL 计划基线中。然后,该计划将用于执行相应的语句。
如果某个SQL 语句存在计划基线,并且初始化参数OPTIMIZER_USE_SQL_PLAN_BASELINES 被设置为TRUE(默认值),则优化程序将使用比较计划选择策略。每次编译SQL 语句时,优化程序都会先使用传统的基于成本的搜索方法建立一个最佳成本计划,然后尝试在SQL 计划基线中找到一个匹配的计划。如果找到了匹配的计划,则优化程序将照常继续运行。如果未找到匹配的计划,则优化程序会先将新计划添加到计划历史记录中,然后计算SQL计划基线中各个已接受的计划的成本,并选择成本最低的那个计划。使用随各个已接受的计划存储的大纲复制这些已接受的计划。因此,对于SQL 语句来说,拥有一个SQL 计划基线的好处就是:优化程序始终选择该SQL 计划基线中的一个已接受的计划。
通过SQL 计划管理,优化程序可以生成最佳成本计划,也可以生成基线计划。此信息将被转储在有关解释计划的plan_table 的other_xml 列中。
此外,还可以使用新的dbms_xplain.display_sql_plan_baseline 函数,显示某个计划基线中给定sql_handle 的一个或多个执行计划。如果还指定了plan_name,则将显示相应的执行计划。
注:为了保留向后兼容性,如果用户会话的某个SQL 语句的存储大纲对是活动的,则将使用此存储大纲编译该语句。此外,即使为会话启用了自动计划捕获,也不将优化程序使用存储大纲生成的计划存储在SMB 中。
虽然存储大纲没有任何显式迁移过程,但可使用DBMS_SPM 程序包中的LOAD_PLAN_FROM_CURSOR_CACHE 过程或LOAD_PLAN_FROM_SQLSET 过程将其迁移到SQL 计划基线。迁移完成时,应禁用或删除原始的存储大纲。
七. 可能的SQL 计划可管理性方案
(1) 数据库升级:
将系统从较早的版本升级到Oracle Database 11g 时,成批加载SQL 计划特别有用。为此,可以在升级前将某个SQL 工作量的计划捕获到SQL 优化集(STS)中,然后在升级后立即将这些计划从STS 加载到SQL 计划基线中。此策略可以最大程度地减少使用新的优化程序版本所导致的计划回归。
(2) 新应用程序部署:
部署新的应用程序模块意味着在系统中引入新的SQL 语句。软件供应商可以将应用程序软件与新引入的SQL 语句的相应SQL 计划基线一起提供。由于存在计划基线,新的SQL 语句最初将与已知在标准测试配置下具有良好性能的计划一起运行。但是,如果客户系统配置与测试配置有很大的差异,则计划基线可随时间演化以产生更好的性能。
在上述两种情况下,都可以在手动加载后使用自动SQL 计划捕获,以确保仅将较好的计划用于将来的应用程序。
八.SQL 性能分析器和SQL 计划基准方案
第一种方法的一个变体是通过使用SQL性能分析器。可以捕获STS 中Oracle Database11g 之前的计划,并将这些计划导入到Oracle Database 11g。然后,将初始化参数optimizer_features_enable 设置为10g,使优化程序将此数据库当成10g Oracle DB 进行操作。接下来,为STS 运行SQL 性能分析器。运行完成后,将初始化参数optimizer_features_enable设置回11g,并为STS 重新运行SQL 性能分析器。
SQL 性能分析器将生成一个报表,列出了从10g 到11g 其计划已发生回归的SQL语句。
对于那些SQL 性能分析器显示的由于新优化程序版本而发生性能回归的SQL 语句,可以使用STS 捕获其计划,然后将这些计划加载到SMB 中。
此方法提供了计划植入进程的最佳形式,因为它有助于在保留数据库升级所带来的性能改进的同时,防止性能回归。
九.自动加载SQL 计划基线:方案
另一种升级方案涉及使用自动SQL计划捕获机制。在此方案中,在最初一段时间(如一个季度)内将初始化参数OPTIMIZER_FEATURES_ENABLE(OFE) 设置为OracleDatabase 11g 之前的版本值,再在升级后使用自动SQl 计划捕获来执行您的工作量。
在这个初始时段中,由于OFE 的参数设置,优化程序可以为大部分SQL 语句复制OracleDatabase 11g 之前的计划。因为在此期间内还启动了自动SQL 计划捕获,所以优化程序生成的Oracle Database 11g 之前的计划将被捕获为SQL 计划基线。
初始时段结束时,可以删除OFE 的设置,以便在因计划基线而出现最小计划回归时或无计划回归时,利用新的优化程序版本。回归的计划将使用以前的优化程序版本;未回归的语句将受益于新的优化程序版本。
十.清除SQL 管理库策略
系统将参照定义的限制,按周检查SQL管理库(SMB) 占用的空间。限制是根据SYSAUX表空间的百分比大小定义的。默认情况下,SMB 的空间预算限制被设置为SYSAUX 大小的10%。但是,可以使用DBMS_SPM.CONFIGURE 过程配置SMB,将空间预算更改为介于1% 和50% 之间的一个值。
如果SMB 空间超过了定义的百分比限制,则会向预警日志中写入警告。通过清除一些SQL管理对象(如SQL 计划基线或SQL 概要文件)来增加SMB 空间限制、增加SYSAUX 大小或者减小SMB 大小之前,将按周生成警报。
SQL 计划基线的空间管理将使用每周清除任务提前完成。该任务在维护窗口中作为自动化任务运行。超过53 周未使用的任何计划都将被清除。但是,可以配置SMB,将未使用计划保留期设置为介于5 周和523 周(比10 年稍长一些)之间的一个值。为此,可使用DBMS_SPM.CONFIGURE 过程。
可以通过检查DBA_SQL_MANAGEMENT_CONFIG视图来查看SMB 的当前配置设置。此外,还可以使用DBMS_SPM.DROP_SQL_PLAN_BASELINE函数手动清除SMB。
更多内容参考:
Using SQL Plan Management
http://docs.oracle.com/cd/E11882_01/server.112/e16638/optplanmgmt.htm