参见昨天Roger的文章,exchange outline可以同样实现这种需求
参考JL的文章:
Stored Outlines in Oracle 8
Stored Outlines in Oracle 9
测试环境:rhel 5.8 oracle 11.2.0.3 64bit
[root@db-2-15 ~]# su - oracle -bash-3.2$ sqlplus 'liu/liu' SQL*Plus: Release 11.2.0.3.0 Production on Fri Sep 14 10:28:51 2012 Copyright (c) 1982, 2011, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options SQL> drop table liu; Table dropped. SQL> create table liu (id int); Table created. SQL> begin 2 for 3 i in 1..1000000 loop 4 insert into liu values (i); 5 commit; 6 end loop; 7 end; 8 / PL/SQL procedure successfully completed. SQL> SQL> SQL> SQL> create index idx_test on liu (id); Index created. SQL> commit; Commit complete. SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'LIU',TABNAME=>'LIU', CASCADE=>TRUE); PL/SQL procedure successfully completed.
SQL> EXPLAIN PLAN FOR SELECT * FROM LIU WHERE ID =7000;
Explained.
SQL> select plan_table_output from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1128569081
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 3 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_TEST | 1 | 5 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 - access("ID"=7000)
13 rows selected.
SQL> EXPLAIN PLAN FOR SELECT /*+full(a) */ * FROM LIU a WHERE ID =7000;
Explained.
SQL> select plan_table_output from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3882242470
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 459 (4)| 00:00:06 |
|* 1 | TABLE ACCESS FULL| LIU | 1 | 5 | 459 (4)| 00:00:06 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 - filter("ID"=7000)
13 rows selected.
创建两个outline(nohint,withhint) -Category TEST
SQL> CREATE OR REPLACE OUTLINE nohint for category test ON SELECT * FROM LIU a WHERE ID =7000; Outline created. SQL> create or replace outline withhint for category test on SELECT /*+full(a) */ * FROM LIU a WHERE ID =7000; Outline created. NAME CATEGORY USED SQL_TEXT ------------------------------ ------------------------------ ------------------ -------------------------------------------------------------------------------- NOHINT TEST UNUSED SELECT * FROM LIU a WHERE ID =7000 WITHHINT TEST UNUSED SELECT /*+full(a) */ * FROM LIU a WHERE ID =7000 SQL> alter session set use_stored_outlines = TEST; Session altered.
进入outln Schema 的outln相关表, 调换两个存储概要的实际内容.
SQL> update outln.ol$ ol1
set hintcount = (
select count(*)
from outln.ol$hints ol2
where ol2.ol_name = ol1.ol_name
)
where
ol1.ol_name in ('NOHINT','WITHHINT') 2 3 4 5 6 7 8
9 ;
2 rows updated.
SQL> commit;
Commit complete.
SQL> UPDATE OUTLN.OL$HINTS
SET OL_NAME=DECODE(OL_NAME, 'NOHINT', 'WITHHINT','WITHHINT','NOHINT')
WHERE OL_NAME IN ('NOHINT','WITHHINT'); 2 3
12 rows updated.
SQL> commit;
Commit complete.
SQL> conn liu/liu
Connected.
SQL> alter session set use_stored_outlines = TEST;
Session altered.
SQL> alter outline NOHINT disable;
alter outline NOHINT enable;
alter outline WITHHINT disable;
alter outline WITHHINT enable;
Outline altered.
SQL>
Outline altered.
SQL>
Outline altered.
SQL>
Outline altered.
SQL> EXPLAIN PLAN FOR SELECT /*+full(a) */ * FROM LIU a WHERE ID =7000;
Explained.
SQL> select plan_table_output from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1128569081
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 3 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_TEST | 1 | 5 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 - access("ID"=7000)
Note
-----
- outline "WITHHINT" used for this statement
17 rows selected.
SQL> EXPLAIN PLAN FOR SELECT * FROM LIU a WHERE ID =7000;
Explained.
SQL> select plan_table_output from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3882242470
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 459 (4)| 00:00:06 |
|* 1 | TABLE ACCESS FULL| LIU | 1 | 5 | 459 (4)| 00:00:06 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 - filter("ID"=7000)
Note
-----
- outline "NOHINT" used for this statement
17 rows selected.
此时已经发生了交换
同理如果没有使用绑定变量同样可以交换,我们假设两个不同的值 这里使用Enkitec提供的脚本
SQL> CREATE OR REPLACE OUTLINE nohint1 for category test ON SELECT * FROM LIU a WHERE ID =6000;
Outline created.
SQL> CREATE OR REPLACE OUTLINE withhint1 for category test ON SELECT /*+full(a) */ * FROM LIU a WHERE ID =500;
Outline created.
SQL> alter session set use_stored_outlines = TEST;
SQL> @exchange_ol
Enter value for from_name: NOHINT1
old 6: fromname := '&from_name';
new 6: fromname := 'NOHINT1';
Enter value for to_name: WITHHINT1
old 7: toname := '&to_name';
new 7: toname := 'WITHHINT1';
PL/SQL procedure successfully completed.
Commit complete.
SQL>
SQL>
SQL>
SQL> EXPLAIN PLAN FOR SELECT /*+full(a) */ * FROM LIU a WHERE ID =500;
Explained.
SQL> select plan_table_output from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1128569081
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 3 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_TEST | 1 | 5 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 - access("ID"=500)
Note
-----
- outline "WITHHINT1" used for this statement
17 rows selected.
SQL> EXPLAIN PLAN FOR SELECT * FROM LIU a WHERE ID =6000;
Explained.
SQL> select plan_table_output from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3882242470
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 459 (4)| 00:00:06 |
|* 1 | TABLE ACCESS FULL| LIU | 1 | 5 | 459 (4)| 00:00:06 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 - filter("ID"=6000)
Note
-----
- outline "NOHINT1" used for this statement
17 rows selected.
此时同样发生了交换