从11.1版本开始,SQL计划管理(SPM)取代了存储概要。其实,可以将SQL计划管理看作是存储概要的增强版。实际上,它们之间不仅具有相同的特性,并且SQL计划管理也具有同样的设计目的,即使执行环境或对象统计信息发生改变,也可以提供稳定的执行计划。此外,与存储概要一样,SQL计划管理也可以在不修改应用的情况下对应用进行优化。
警告 Oracle文档中唯一提到的SQL计划管理的用法是稳定执行计划。并未提及在不修改提交SQL语句的应用的情况下使用SQL计划管理来改变当前的执行计划(与某个给定的SQL语句相关),出于某些原因,我也选择忽略该功能。
下面是SQL计划管理包含的关键元素。
Ø SQL计划基线:用来稳定执行计划的实际对象。
Ø 语句日志:之前执行过的SQL语句列表。
Ø SQL管理基础(SMB):存储SQL计划基线和语句日志的位置。需要的空间是在sysaux表空间中分配的。
1.1.1 工作原理
1.1.1.1 什么是SQL计划基线
SQL计划基线是用来影响查询优化器生成执行计划的对象。更具体一点,SQL基线包含了一个或多个执行计划,而执行计划里包含一组hint。基本上,SQL计划基线用于强迫查询优化器针对给定SQL语句生成特定的执行计划。
警告 并不是所有的hint都会存储在SQL计划基线中。可以执行下面的查询来查明不会存储哪些hint:
select name FROM v$sql_hint WHERE
version_outline IS NULL;
即使大多数hint无法保存在SQL计划基线中也不会影响到执行计划(例如,gather_plan_statistics),但其中一些会影响(例如,materialize和inline)。因此,对于有些执行计划,如果不增加hint,在SQL语句中是无法通过SQL计划基线来强制修改的。
SQL计划基线的其中一个优势它适用于某个特定SQL语句,并且不需要修改SQL语句本身。实际上,SQL计划基线存储在SQL基础管理平台上,并且查询优化器会自动选择它们。图11-8显示了选择期间执行的基本步骤。
(1)首先,SQL语句按照正常方法解析。换句话说,查询优化器不使用SQL计划基线生成执行计划。
(2)接着,查询优化器会将SQL语句标准化,使其不区分大小写并且与文本中的空格无关。计算出产生的SQL语句的签名,然后在SQL基础管理平台中执行查找。如果找到相同签名的SQL计划基线,就会执行检查来确保SQL语句是最优的,并且与关联SQL计划基线的SQL语句是等价的。这一步是必要的检查,因为签名是散列值,因此可能存在冲突。
(3)检查成功后,查询优化器会核实SQL计划基线是否包含没有使用SQL计划基线生成的执行计划。如果包含它并且接受(信任)它,就会执行它。
(4)如果将另外一个接受的执行计划存储在SQL计划基线中,那么与它相关的hint会用来生成另一个执行计划。请注意如果SQL计划基线包含多个接受的执行计划,查询优化器会选择代价最小的那个。
(5)最后,查询优化器检查利用SQL计划基线生成的执行计划是否会重现预估的执行计划。只有最后这个检查满足条件时,执行计划才可用。如果这个检查通不过,查询优化器会尝试其他接受的执行计划,如果所有的执行计划都无法重现,它会选择没有使用SQL计划基线生成的执行计划。
图11-8 SQL计划基线选择期间执行的主要步骤