IDX_T2 24000000
zx@MYDB>select object_id,object_name from t2 where object_id between 103 and 108;
OBJECT_ID OBJECT_NAME
---------- ------------------------------
103 MIGRATE$
104 DEPENDENCY$
105 ACCESS$
106 I_DEPENDENCY1
107 I_DEPENDENCY2
108 I_ACCESS1
6 rows selected.
从执行计划中可以看出该SQL的执行计划已经变为全表扫描。因为目标SQL已经重复执行且同时又产生了一个新的执行计划,所以现在Oracle就会自动捕获并创建这个新的执行计划所对应的SQL Plan Baseline了。从如下查询可以看出Oracle对新的执行计划产生了一个新的SQL Plan Baseline,其ENABLED的值依然为YES,但ACCEPTED的值变为了NO:
现在我们对当前Session关闭自动捕获SQL Plan Baseline并同时开启SPM,现在索引IDX_T2的聚簇因子依然为2400万,再次执行目标SQL,并查看执行计划:
zx@MYDB>alter session set optimizer_use_sql_plan_baselines=TRUE;
Session altered.
zx@MYDB>alter session set optimizer_capture_sql_plan_baselines=FALSE;
Session altered.
zx@MYDB>select index_name,clustering_factor from dba_indexes where index_name='IDX_T2';
INDEX_NAME CLUSTERING_FACTOR
------------------------------------------------------------------------------------------ -----------------
IDX_T2 24000000
zx@MYDB>select object_id,object_name from t2 where object_id between 103 and 108;
OBJECT_ID OBJECT_NAME
---------- ------------------------------
103 MIGRATE$
104 DEPENDENCY$
105 ACCESS$
106 I_DEPENDENCY1
107 I_DEPENDENCY2
108 I_ACCESS1
6 rows selected.
从上面的显示内容可以看出,现在目标SQL的执行又从全表扫描恢复为了索引范围扫描,并且执行计划中的Note部分有“SQL plan baseline SQL_PLAN_asnmb3t5yfk4024c6dbb6 used for this statement”内容,说明SPM开启的情况下,即便目标SQL产生了新的执行计划,Oracle依然只会应用该SQL的ENABLED和ACCEPTED的值均为YES的SQL Plan Baselline。
如果想启用目标SQL新的执行计划(即全表扫描),应该如何做呢?
针对不同的Oracle版本,会有不同的处理方法。比如这里想启用目标SQL的新的执行计划,如果是11gR1的环境,则只需要将目标SQL所采用的名为SQL_PLAN_asnmb3t5yfk4024c6dbb6的SQL Plan Baseline(即索引范围扫描)的ACCEPTED的值设为NO就可以了。但对于11gR2环境,上述方法会报错,因为在11gR2中,所有已经被ACCEPTED的SQL Plan Baseline的ACCEPTED的值将不再能够被设为NO:
zx@MYDB>var temp varchar2(1000);