关于Oracle Outline使用(2)

1、更改outline名称

alter outline SYS_OUTLINE_14061114223605901 rename to dh_test2

2、更改outline类别

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

3、重建outline

alter outline DH_TEST2 rebuild;

三、激活outline

Oracle优化器只会考虑激活的outline,这意味着如果创建的outline没有被激活,Oracle根本不会使用它,一个outline必须满足如下两个条件才能被激活:

1、outline必须处于可用状态(创建时默认就是可用,一般不会有问题),修改方法,alter outlineDH_TEST2 disable;

2、类别必须通过初始化参数use_stored_ouotlines在会话或者系统级激活,可以设置为“TRUE/FALSE/类别名”三种,其中TRUE表示启用default类别

alter session set use_stored_outlines=TRUE;

四、移动outline

只能通过将数据字典中保存的hint数据复制到另一个数据库的数据字典,除此之外没有其它办法。不过还好这个方法也非常简单,因为outline相关的hint数据都保存在outln用户下的三张表中:ol$、ol$hints、ol$nodes。可以用下面的命令来导入和导出可用的outline

exp tables=(outln.ol$,outln.ol$hints,outln.ol$nodes) file=xxx.dmp

五、编辑outline,后续会提供两种方法

当优化器无法为给定的SQL生成高效的执行计划时,可以通过编辑outline来实现,可以理解为修改outline中的hint

1、使用原语句建Outline

2、查看Outline执行计划


Select HINT_TEXT,USER_TABLE_NAME,JOIN_PRED,cardinality,bytes,cost
from OUTLN.OL$HINTS
where ol_name = 'OLXXXXX_ORIG' 

3、在SQL上加hint,执行语句(注意语句结构不能改变,不能增加或删除查询块什么的)

4、查看加上hint的SQL语句,执行计划是否与我们期望的一致

5、得到期望的执行计划后,将两个outline的执行计划进行互换,即完成outline的编辑!

UPDATE OUTLN.OL$HINTS
SET OL_NAME = DECODE(OL_NAME,
'OLXXXXX_MOD',
'OLXXXXX_ORIG',
'OLXXXXX_ORIG',
'OLXXXXX_MOD')
WHERE OL_NAME IN ('OLXXXXX_MOD', 'OLXXXXX_ORIG');

6、启用outline

六、删除outline

可以用如下命令分别删除指定的outline或者某个类别下的所有outline

drop outline dh_test1;

dbms_outln.drop_by_cat(cat=>'test');

示例一(引用使用共享池中的SQL来创建outline)

SQL> create table dh_stat as select rownum id ,object_name name ,object_type type from dba_objects;

SQL> create index ind_1 on dh_stat(id) compute statistics;

SQL> alter system flush shared_pool;
系统已更改。
SQL> exec DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'dbmon',TABNAME=>'dh_stat',ESTIMATE_PERCENT=>30,METHOD_OPT=>'FOR ALL COLUMNS SIZE 1',NO_INVALIDATE=>FALSE,CASCADE=>TRUE,DEGREE => 1);
 PL/SQL 过程已成功完成。
SQL> col name format a15
SQL> col name format a30
SQL> col sql_text format a55

给运行的语句添加一个独特的注释,方便后续查找语句
SQL> select /* outlinetest1 */ * 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 '%outlinetest1%' and sql_text not like '%v$sql%';
 SQL_TEXT SQL_ID HASH_VALUE CHILD_NUMBER
------------------------------------------------------- ------------- ---------- ------------
select /* outlinetest1 */ * from dh_stat where id=771 053nzgm4f6rdr 3370343863 0
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)
已选择19行。

SQL> exec DBMS_OUTLN.create_outline(hash_value=>3370343863,child_number => 0,category=>'TEST');
 PL/SQL 过程已成功完成。
SQL> col category format a10
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
可以看到,outline确实已经生成
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_14061209594622403 TEST UNUSED select /* outlinetest1 */ * from dh_stat whereid=771
此处outline的USED状态没有改变,因为我们没有激活TEST类别的outline,再次申明,outline必须通过use_stored_outlines参数激活后,优化器才会使用outline!
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)
已选择19行。
 下面这一步激活TEST类别的OUTLINE,也可以在系统级激活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 name,category,used,sql_text from dba_outlines;

NAME CATEGORY USED SQL_TEXT
------------------------------ ---------- ------ -------------------------------------------------------
 SYS_OUTLINE_14061209594622403 TEST USED select /* outlinetest1 */ * from dh_stat where id=771

再次查询OUTLINE的使用状态,可以看到,我们刚新建的outline确实已经被使用过,通过下面的执行计划,更加可以证实这一点
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
已选择42行。

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

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