调整执行计划的三种方法

来源:互联网 发布:重庆sem优化 编辑:程序博客网 时间:2024/05/01 01:16

当我们碰到SQL的执行计划不正确的情况,可能会有几个选择:第一,通过调整统计信息来改变执行计划;第二,通过在SQL上加hint改变执行计划。但是某些情况下,系统中的SQL不能修改,调整统计信息也不能解决问题(分析统计信息也是一个风险比较大的操作,因为可能会影响到很多相关的SQL),这时我们就要用到一些调整或固化执行计划的方法,下面简要介绍以下三种方法:stored outline(9i),SQL profile(10g)和SQL plan baseline

(11g)。

其实这三种方法从本质上说都差不多,Oracle根据SQL语句计算一个signature,用来标识这个SQL,然后为这个SQL施加一系列hint,以达到调整或固化执行计划的目的,并将其存入数据字典中。在SQL执行时,首先根据SQL的signature去数据字典中寻找对应的SQL,如果存在的话,则优化器会根据记录的hint来调整执行计划。

1.stored outline

stored outline是Oracle 9i中提供的调整执行计划的方法。这里有一个小技巧:如果在生产环境中,我们不能通过调整统计信息让SQL生成正确的执行计划,这样就没有办法生成正确的outline,这时我们可以在SQL上添加hint,强制SQL走到正确的执行计划上,然后生成outline,由于此时SQL text发生了变化导致signature变化,需要直接修改outline的字典表ol$hints,交换两个hint的OL_NAME字段,用此方法来产生SQL的stored outline.

2.SQL profile

Oracle 10g提出了SQL Tuning Advisor这个工具,其核心是Automatic Tuning Optimizer,它是Query Optimizer的一个扩展,我们都知道在SQL真实执行时,为了性能的考虑,优化器并不会分析所有可能的执行计划,而ATO则专门为了优化SQL而产生,其主要功能就是分析SQL语句,并给出一些提高性能的建议。

Oracle提供了一个包:dbms_sqltune,我们可以用这个包创建一个tuning task,通过Tuning Optimizer对SQL进行分析后,就可以产生一个SQL profile,用户可以选择接受这个profile,则SQL的执行计划会受到影响。SQL profile是影响SQL执行计划的一系列信息的集合,可能包括环境(参数)设置,统计信息,优化器估算的信息,hint等等。

我们可以看到相比stored outline,Oracle提供了dbms_sqltune这个包,通过Automatic Tuning Optimizer自动产生SQL profile,并且report_tuning_task可以为用户提供详细的报告,而且SQL profile中包含的信息也更多。但是SQL profile只能通过Oracle自动产生,没有办法“人工”创建。

3.SQL plan baseline

Oracle 11g推出了SQL plan baseline,最大的特点就是为SQL的执行计划加入了版本的概念,并且当执行计划发生变化时,允许用户对其进行控制,对于OLTP系统来说,这是个非常重要的特性。

首先系统需要收集SQL plan baseline,可以通过参数打开系统自动收集,Oracle提供了一个包,dbms_spm,也可以通过这个包从library cache中获取。每当SQL产生新的执行计划时,Oracle都会将其记录下来,但是这个执行计划并不会马上生效。每个SQL用SQL_ID标识,SQL plan baseline中包含这个SQL的若干个执行计划,SQL plan baseline用SQL_handle标识,每个PLAN都有plan_name和plan_hash_value。

 

如果某个SQL有很多plan,我们要选择哪一个plan?Oracle提供了Evolving SQL plan baseline的功能,通过evolve_sql_plan_baseline这个函数,可以对不同的plan进行比较,其实就是让优化器直接执行SQL的不同plan,以此来选择最优的plan,并且可以给出详细的报告。

SQL plan baseline同样提供了人为调整执行计划的方法,通过hint或者调整统计信息,得到SQL的执行计划,然后通过load_plans_from_cursor_cache函数,将这个plan装载到SQL plan baseline中。

通过SQL plan baseline我们就可以控制SQL的执行计划,当执行计划发生变化时,并不会马上生效,而是等待用户确认,这样大大降低了系统的风险。用户可以通过alter_sql_plan_baseline更改当前生效的plan。

BTW:Oracle 11g提供了很多非常nice的功能,SQL plan baseline也算是其中一个吧。