关于Oracle Outline使用(3)

1、第一种是直接修改字典里的hint,这里就不测试了。

2、通过更换两个outline名称,来完成修改

--这个实验紧接着“示例一(引用使用共享池中的SQL来创建outline)"

SQL> exec dbms_outln.clear_used(name=>'SYS_OUTLINE_14061209594622403');
 PL/SQL 过程已成功完成。

---通过上面的过程,将outline的使用记录清理掉,USED状态再次转变为UNSED,方便我们测试
SQL> select name,category,used,sql_text from dba_outlines;
NAME CATEGORY USED SQL_TEXT
------------------------------ ---------- ------ -------------------------------------------------------
 SYS_OUTLINE_14061209594622403 TEST UNUSED select /* outlinetest1 */ * from dh_stat whereid=771
SQL> select /* outlinetest2 */ /*+ full(dh_stat) */ * from dh_stat where id=771;
 ID NAME TYPE
---------- ------------------------------ ---------------
771 APPLY$_CONF_HDLR_COLUMNS_UNQ1 INDEX
SQL> select sql_text,sql_id,hash_value,child_number from v$sql a where sql_text like '%outlinetest2%' and sql_text not like '%v$sql%';
 SQL_TEXT SQL_ID HASH_VALUE CHILD_NUMBER
------------------------------------------------------- ------------- ---------- ------------
select /* outlinetest2 */ /*+ full(dh_stat) */ * from d 3fcq9c8xu4a92 1000483106 0
 h_stat where id=771
SQL> alter session set use_stored_outlines=true;
会话已更改。
SQL> select * from table(dbms_xplan.display_cursor('3fcq9c8xu4a92','',''));
 PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------------------------
 SQL_ID 3fcq9c8xu4a92, child number 0
-------------------------------------
select /* outlinetest2 */ /*+ full(dh_stat) */ * from dh_stat where
 id=771
 Plan hash value: 1845196118
-----------------------------------------------------------------------------
 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
 | 0 | SELECT STATEMENT | | | | 124 (100)| |
 |* 1 | TABLE ACCESS FULL| DH_STAT | 1 | 38 | 124 (1)| 00:00:02 |
-----------------------------------------------------------------------------
 Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("ID"=771)
已选择19行。

SQL> exec DBMS_OUTLN.create_outline(hash_value=>1000483106,child_number => 0,category=>'TEST');
 PL/SQL 过程已成功完成。
SQL> select name,category,used,sql_text from dba_outlines;

NAME CATEGORY USED SQL_TEXT
------------------------------ ---------- ------ -------------------------------------------------------
 SYS_OUTLINE_14061210153067004 TEST UNUSED select /* outlinetest2 */ /*+ full(dh_stat) */ * from d
 h_stat where id=771
 SYS_OUTLINE_14061209594622403 TEST UNUSED select /* outlinetest1 */ * from dh_stat whereid=771
可以看到,我们新建的outline,确实已经成功
SQL> alter session set use_stored_outlines=TEST;
会话已更改。
SQL> select /* outlinetest1 */ * from dh_stat where id=771;
 ID NAME TYPE
---------- ------------------------------ ---------------
771 APPLY$_CONF_HDLR_COLUMNS_UNQ1 INDEX
SQL> select /* outlinetest2 */ /*+ full(dh_stat) */ * from dh_stat where id=771;
 ID NAME TYPE
---------- ------------------------------ ---------------
771 APPLY$_CONF_HDLR_COLUMNS_UNQ1 INDEX
SQL> select name,category,used,sql_text from dba_outlines;
NAME CATEGORY USED SQL_TEXT
------------------------------ ---------- ------ -------------------------------------------------------
 SYS_OUTLINE_14061210153067004 TEST USED select /* outlinetest2 */ /*+ full(dh_stat) */ * from d
 h_stat where id=771
 SYS_OUTLINE_14061209594622403 TEST USED select /* outlinetest1 */ * from dh_stat where id=771
可以看到,两个outline都已经标记为已经使用过
SQL> select * from table(dbms_xplan.display_cursor('3fcq9c8xu4a92','',''));
 PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------------------------
 SQL_ID 3fcq9c8xu4a92, child number 0
-------------------------------------
select /* outlinetest2 */ /*+ full(dh_stat) */ * from dh_stat where
 id=771
 Plan hash value: 1845196118
-----------------------------------------------------------------------------
 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
 | 0 | SELECT STATEMENT | | | | 124 (100)| |
 |* 1 | TABLE ACCESS FULL| DH_STAT | 1 | 38 | 124 (1)| 00:00:02 |
-----------------------------------------------------------------------------
 Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("ID"=771)
 Note
-----
 - outline "SYS_OUTLINE_14061210153067004" used for this statement
已选择23行。

SQL> select * from table(dbms_xplan.display_cursor('053nzgm4f6rdr','',''));
 PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------------------------
 ....此处为了排版,省略了一个child number 0 的执行计划!........

SQL_ID 053nzgm4f6rdr, child number 1
-------------------------------------
select /* outlinetest1 */ * from dh_stat where id=771
 Plan hash value: 2780970545
---------------------------------------------------------------------------------------
 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
 | 0 | SELECT STATEMENT | | | | 2 (100)| |
 | 1 | TABLE ACCESS BY INDEX ROWID| DH_STAT | 1 | 38 | 2 (0)| 00:00:01 |
 |* 2 | INDEX RANGE SCAN | IND_1 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
 Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=771)
 Note
-----
- outline "SYS_OUTLINE_14061209594622403" used for this statement
已选择42行。
SQL> alter session set use_stored_outlines=TRUE;
会话已更改。

通过如下方式,我们调换两个outline里面的hints
SQL> UPDATE OUTLN.OL$HINTS
 2 SET OL_NAME = DECODE(OL_NAME,
 3 'SYS_OUTLINE_14061210153067004',
 4 'SYS_OUTLINE_14061209594622403',
 5 'SYS_OUTLINE_14061209594622403',
 6 'SYS_OUTLINE_14061210153067004')
 7 WHERE OL_NAME IN ('SYS_OUTLINE_14061210153067004', 'SYS_OUTLINE_14061209594622403');
已更新12行。
SQL> commit;
提交完成。
SQL> col hint_text format a50
SQL> select hint#,hint_text from outln.ol$hints a where ol_name='SYS_OUTLINE_14061209594622403';
 HINT# HINT_TEXT
---------- --------------------------------------------------
1 FULL(@"SEL$1" "DH_STAT"@"SEL$1")
2 OUTLINE_LEAF(@"SEL$1")
3 ALL_ROWS
4 DB_VERSION('11.2.0.1')
5 OPTIMIZER_FEATURES_ENABLE('11.2.0.1')
6 IGNORE_OPTIM_EMBEDDED_HINTS
已选择6行。
 果然和我们预期的一样,outline里面的执行计划已经调换
SQL> select /* outlinetest1 */ * from dh_stat where id=771;

ID NAME TYPE
---------- ------------------------------ ---------------
771 APPLY$_CONF_HDLR_COLUMNS_UNQ1 INDEX
SQL> select * from table(dbms_xplan.display_cursor('053nzgm4f6rdr','',''));
 PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------------------------
 SQL_ID 053nzgm4f6rdr, child number 0
-------------------------------------
select /* outlinetest1 */ * from dh_stat where id=771
 Plan hash value: 2780970545
---------------------------------------------------------------------------------------
 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
 | 0 | SELECT STATEMENT | | | | 2 (100)| |
 | 1 | TABLE ACCESS BY INDEX ROWID| DH_STAT | 1 | 38 | 2 (0)| 00:00:01 |
 |* 2 | INDEX RANGE SCAN | IND_1 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
 Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=771)
 SQL_ID 053nzgm4f6rdr, child number 1
-------------------------------------
select /* outlinetest1 */ * from dh_stat where id=771
 Plan hash value: 2780970545
---------------------------------------------------------------------------------------
 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
 | 0 | SELECT STATEMENT | | | | 2 (100)| |
 | 1 | TABLE ACCESS BY INDEX ROWID| DH_STAT | 1 | 38 | 2 (0)| 00:00:01 |
 |* 2 | INDEX RANGE SCAN | IND_1 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
 Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=771)
 Note
-----
- outline "SYS_OUTLINE_14061209594622403" used for this statement
 SQL_ID 053nzgm4f6rdr, child number 2
-------------------------------------
select /* outlinetest1 */ * from dh_stat where id=771

Plan hash value: 2780970545

---------------------------------------------------------------------------------------
 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
 | 0 | SELECT STATEMENT | | | | 2 (100)| |
 | 1 | TABLE ACCESS BY INDEX ROWID| DH_STAT | 1 | 38 | 2 (0)| 00:00:01 |
 |* 2 | INDEX RANGE SCAN | IND_1 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("ID"=771)
已选择61行。
 激活outline
SQL> alter session set use_stored_outlines=TEST;
会话已更改。

SQL> exec dbms_outln.clear_used(name=>'SYS_OUTLINE_14061209594622403');
 PL/SQL 过程已成功完成。

SQL> select name,category,used,sql_text from dba_outlines;

NAME CATEGORY USED SQL_TEXT
------------------------------ ---------- ------ -------------------------------------------------------
 SYS_OUTLINE_14061210153067004 TEST USED select /* outlinetest2 */ /*+ full(dh_stat) */ * from d
 h_stat where id=771
 SYS_OUTLINE_14061209594622403 TEST UNUSED select /* outlinetest1 */ * from dh_stat whereid=771

SQL> select /* outlinetest1 */ * from dh_stat where id=771;

ID NAME TYPE
---------- ------------------------------ ---------------
771 APPLY$_CONF_HDLR_COLUMNS_UNQ1 INDEX

SQL> select name,category,used,sql_text from dba_outlines;

NAME CATEGORY USED SQL_TEXT
------------------------------ ---------- ------ -------------------------------------------------------
 SYS_OUTLINE_14061210153067004 TEST USED select /* outlinetest2 */ /*+ full(dh_stat) */ * from d
 h_stat where id=771
 SYS_OUTLINE_14061209594622403 TEST USED select /* outlinetest1 */ * from dh_stat where id=771

SQL> select * from table(dbms_xplan.display_cursor('053nzgm4f6rdr','',''));
 PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------
 SQL_ID 053nzgm4f6rdr, child number 0
-------------------------------------
select /* outlinetest1 */ * from dh_stat where id=771
 Plan hash value: 2780970545
---------------------------------------------------------------------------------------
 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
 | 0 | SELECT STATEMENT | | | | 2 (100)| |
 | 1 | TABLE ACCESS BY INDEX ROWID| DH_STAT | 1 | 38 | 2 (0)| 00:00:01 |
 |* 2 | INDEX RANGE SCAN | IND_1 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
 Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=771)
 SQL_ID 053nzgm4f6rdr, child number 1
-------------------------------------
select /* outlinetest1 */ * from dh_stat where id=771
 Plan hash value: 2780970545
---------------------------------------------------------------------------------------
 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
 | 0 | SELECT STATEMENT | | | | 2 (100)| |
 | 1 | TABLE ACCESS BY INDEX ROWID| DH_STAT | 1 | 38 | 2 (0)| 00:00:01 |
 |* 2 | INDEX RANGE SCAN | IND_1 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
 Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=771)
 Note
-----
- outline "SYS_OUTLINE_14061209594622403" used for this statement
 SQL_ID 053nzgm4f6rdr, child number 2
-------------------------------------
select /* outlinetest1 */ * from dh_stat where id=771
 Plan hash value: 2780970545
---------------------------------------------------------------------------------------
 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
 | 0 | SELECT STATEMENT | | | | 2 (100)| |
 | 1 | TABLE ACCESS BY INDEX ROWID| DH_STAT | 1 | 38 | 2 (0)| 00:00:01 |
 |* 2 | INDEX RANGE SCAN | IND_1 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
 Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("ID"=771)
 SQL_ID 053nzgm4f6rdr, child number 3
-------------------------------------
select /* outlinetest1 */ * from dh_stat where id=771
 Plan hash value: 2780970545
---------------------------------------------------------------------------------------
 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
 | 0 | SELECT STATEMENT | | | | 2 (100)| |
 | 1 | TABLE ACCESS BY INDEX ROWID| DH_STAT | 1 | 38 | 2 (0)| 00:00:01 |
 |* 2 | INDEX RANGE SCAN | IND_1 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
 Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=771)
 Note
-----
- outline "SYS_OUTLINE_14061209594622403" used for this statement
已选择84行。

可以看到,虽然OUTLINE已经被使用,但是并不是我们预期的那样。想要得到我们预期,通过全表扫描来实现,我在测试中是通过下面的方法实现


SQL> alter session set use_stored_outlines=dd;

会话已更改。

SQL> exec dbms_outln.clear_used(name=>'SYS_OUTLINE_14061209594622403');

PL/SQL 过程已成功完成。

SQL> select /* outlinetest1 */ * from dh_stat where id=771;

ID NAME TYPE

---------- ------------------------------ ---------------

771 APPLY$_CONF_HDLR_COLUMNS_UNQ1 INDEX

SQL> select name,category,used,sql_text from dba_outlines;

NAME CATEGORY USED SQL_TEXT

------------------------------ ---------- ------ -------------------------------------------------------

SYS_OUTLINE_14061210153067004 TEST USED select /* outlinetest2 */ /*+ full(dh_stat) */ * from d

h_stat where id=771

SYS_OUTLINE_14061209594622403 TEST UNUSED select /* outlinetest1 */ * from dh_stat where id=771

SQL> alter session set use_stored_outlines=TRUE;

会话已更改。

SQL> select /* outlinetest1 */ * from dh_stat where id=771;

ID NAME TYPE

---------- ------------------------------ ---------------

771 APPLY$_CONF_HDLR_COLUMNS_UNQ1 INDEX

SQL> select name,category,used,sql_text from dba_outlines;

NAME CATEGORY USED SQL_TEXT

------------------------------ ---------- ------ -------------------------------------------------------

SYS_OUTLINE_14061210153067004 TEST USED select /* outlinetest2 */ /*+ full(dh_stat) */ * from d

h_stat where id=771

SYS_OUTLINE_14061209594622403 TEST UNUSED select /* outlinetest1 */ * from dh_stat where id=771

SQL> exec dbms_outln.update_by_cat(oldcat=>'TEST',newcat=>'DEFAULT');

PL/SQL 过程已成功完成。

SQL> select /* outlinetest1 */ * from dh_stat where id=771;

ID NAME TYPE

---------- ------------------------------ ---------------

771 APPLY$_CONF_HDLR_COLUMNS_UNQ1 INDEX

SQL> select name,category,used,sql_text from dba_outlines;

NAME CATEGORY USED SQL_TEXT

------------------------------ ---------- ------ -------------------------------------------------------

SYS_OUTLINE_14061210153067004 DEFAULT USED select /* outlinetest2 */ /*+ full(dh_stat) */ * from d

h_stat where id=771

SYS_OUTLINE_14061209594622403 DEFAULT USED select /* outlinetest1 */ * from dh_stat where id=771

SQL> select * from table(dbms_xplan.display_cursor('053nzgm4f6rdr','',''));

PLAN_TABLE_OUTPUT

-------------------------------------------------------------------------------------------------------------------

....为了排版,省略了前面的4个子执行计划.........

SQL_ID 053nzgm4f6rdr, child number 4

-------------------------------------

select /* outlinetest1 */ * from dh_stat where id=771

Plan hash value: 1845196118

-----------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

-----------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | | | 124 (100)| |

|* 1 | TABLE ACCESS FULL| DH_STAT | 1 | 38 | 124 (1)| 00:00:02 |

-----------------------------------------------------------------------------

Predicate Information (identified by operation id):

-------------------------------------------------

1 - filter("ID"=771)

Note

-----

- outline "SYS_OUTLINE_14061209594622403" used for this statement

已选择102行。

可以看到,这次outline已经和我们预期的一样生效,并且是通过全表扫描来实现

而且通过多次实验证明,必须修改一下outline的类别名或者将语句刷出共享池才能实现,因此,我们先将outline创建为一个私有的类别,等验证完毕且符合预期后,再正式发布出来,这样也不会需要修改数据库当前已有参数。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/56d89119cf060ca5a0b6e8f16cb6b310.html