我们可以看到,这里已经产生了两个不同的执行计划,注意看PLAN_HASH_VALUE列。
我们来查询一下新产生的PLAN
SQL> select * from table(dbms_xplan.display_cursor('auwza0aq10mk0',1));
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID auwza0aq10mk0, child number 1
-------------------------------------
select * from haha where a='10000'
Plan hash value: 3694936490
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 32 (100)| |
|* 1 | TABLE ACCESS FULL| HAHA | 1 | 11 | 32 (4)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("A"='10000')
18 rows selected. 这个新的PLAN,为全表扫描,是不正确的执行计划
现在我在当前环境下执行该sql,会一直采用这个错误的plan,在业务系统中是很致命的。
SQL> select * from haha where a='10000';
A B
------------------------------ ----------
10000 10000
SQL> select * from table(dbms_xplan.display_cursor());
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID auwza0aq10mk0, child number 1
-------------------------------------
select * from haha where a='10000'
Plan hash value: 3694936490
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 32 (100)| |
|* 1 | TABLE ACCESS FULL| HAHA | 1 | 11 | 32 (4)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("A"='10000')
18 rows selected.
那么我想将正确的执行计划稳定上,该如何做?
通过使用11G的新包,DBMS_SPM就可以实现
SQL BASELINE有两个状态,一个是ENABLED,一个是ACCEPTED,两个都为true,oracle才会使用,如果有同一个SQL的多个SQL_BASELINE存在,且状态都为true,那么会根据成本大小进行判断。(注:当自动捕获开启时,一个SQL,每产生一个不同的执行计划,都会产生一个baseline,enabled都为true,但只有第一个获取的baseline,accepted才为true,其他都为false)
SQL>variable cnt number