固定执行计划

执行计划保留在stored outline中,一个outline是一系列与sql语句相关的优化器hints,如果语句的outline被启用了,oracle自动考虑存放的hints,并试着产生一个与这些hints相关的执行计划。

oracle可以为一个sql或是所有的sql语句产生一个公共的或私有的stored outline。你可以将outline分组并控制oracle使用哪组outline,减少了管理和部署的工作。

oracle在sys表空间中创建了user_outlines和useroiutline_hits视图,这两个视图是基于ol$和ol$hints表的。

oracle存放outline数据在ol$,ol$hints和ol$nodes表中。会一直保存,除非你删除。

启用固定计划

为了使outline能正常使用,需要设置下面的参数

query_rewrite_enabled

start_transformation_enabled

optimizer_features_enable

dbms_outln和dbms_outln_edit包用来提供存储过程来管理outline和他的分类。

一些有用的dbms_outln和dbms_outln_edit存储过程有下面的:

clear_used--清除具体的outline

drop_by_cat清除指定类别的outline

update_by_cat更新指定的类别到别的类别

exact_text_signatures根据具体文本计算outline的签名

generate_signature-为具体的sql文本生成签名。

oracle可以自动为所有的sql生成outline,也可以为具体的sql生成。当你设置了参数create_stored_outlines=true的时候,oralce会自动生成outline。要想为指定的sql生成outline,你需要使用create outline语句。

当创建或编辑一个私有outline的时候,这个outline的数据是在system用户下面的。可以再使用create outline的时候指定具体的类别,不指定的话,就是默认的类别了。

当oracle在编译sql的时候,为了使用存储outline,设置参数use_sotred_outlines=true。这样oracle使用默认类别。如果使用use_stored_outlines参数指定了一个类别,那么oracle使用那个类别直到你改变成别的类别。如果在你指定的类别中oracle没有找到匹配 的outline,那么oracle去默认的类别中取查找。

要是想要使用具体的outline,而不是所有的outline,使用alter outline语句来启用具体outline.要是想要使用类别中的outline,而不是一个具体的outline,使用alter outline来禁用具体的outline。alter outline也可以重命名一个outline,重新分配到别的类别,或重新生成它。

use_private_outlines参数让你控制私有的outline.一个私有的outline只能在当前会话中被看见,并且它的数据存放在当前解析模式下面。

通过直接调整outline,就可以不用修改应用程序来调优sql了。

当use_private_outlines参数被启用,sql语句被执行的时候,优化器在会话私有区域获取outline,而不是公共区域,如果在私有区域没有,那么优化器不会使用outline来编译语句。

任何的create outline语句需要create any outline权限。指定from子句也需要select权限。当开始编辑,ue_private_outlines应该设置成outline所属的类别,编辑完成后,这个参数在设置回false来存放会话到正常outline。

下面是一个编辑outline的例子

假如要编辑oll

1连接到用户

2使用下面的语句克隆outline到私有区

create private outline p_oll from oll;

3编辑outline,使用em或dbms_outln_edit

4如果手工编辑outline,使用dbms_outlin_edit.change_join_pos来改变位置,然后同步outline定义使用下面的语句

exec dbms_outln_edit.refresh_private_outline('S-LL');

create private outline p_oll from pivate p_oll;

5测试编辑。使用use_private_outlines=true,运行explain plan

6如果要保存这些编辑给公共使用,执行下面的语句

create or replace outline oll from private p_oll;

7禁用私有outline

use_private_outlines=false;

怎么看一个outline在被使用

查看v$sql的outline_category和outline_sid列。如果outline_category是null,那么就没有使用outline,如果使用了,那么这列就是显示的类别。outline_sid要是0那么就说明是一个公共outline,要是会话id,那么就是私有outline

SELECT OUTLINE_CATEGORY, OUTLINE_SID
  FROM V$SQL
  WHERE SQL_TEXT LIKE 'SELECT COUNT(*) FROM emp%';

查看outline数据

SELECT NAME, SQL_TEXT
  FROM USER_OUTLINES
  WHERE CATEGORY='mycat';


SELECT HINT
  FROM USER_OUTLINE_HINTS
  WHERE NAME='name1';

SELECT NAME, CATEGORY, ENABLED FROM USER_OUTLINES;


创建outline的例子

1CREATE OUTLINE salaries FOR CATEGORY special
   ON SELECT last_name, salary FROM employees;
2创建一个私有克隆outline

EXECUTE DBMS_OUTLN_EDIT.CREATE_EDIT_TABLES;

CREATE OR REPLACE PRIVATE OUTLINE my_salaries
   FROM salaries;

3将私有outline发布到公共区

CREATE OR REPLACE OUTLINE public_salaries
   FROM PRIVATE my_salaries;


outline测试

SQL> begin
  2  for i in 1 .. 10000 loop
  3  insert into test(owner,object_name,created,last_ddl_time,object_id) values(
'bai','t',sysdate,sysdate,50);
  4  end loop;
  5  end;
  6  /

PL/SQL 过程已成功完成。

SQL> commit;

提交完成。

SQL> select count(*) from test;

  COUNT(*)
----------
     10049

SQL> create outline ol on select * from test where object_id=50;
create outline ol on select * from test where object_id=50
                                   *
第 1 行出现错误:
ORA-18004: 大纲已存在


SQL> drop outline ol;

大纲已删除。

SQL> create outline ol on select * from test where object_id=50;

大纲已创建。

SQL> alter system set use_stored_outlines=ol;

系统已更改。

SQL> set autot trace
SQL> select * from test where object_id=50;

已选择10001行。


执行计划
----------------------------------------------------------
Plan hash value: 1357081020

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     3 |   384 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TEST |     3 |   384 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

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

   1 - filter("OBJECT_ID"=50)

Note
-----
   - outline "OL" used for this statement


统计信息
----------------------------------------------------------
         38  recursive calls
        123  db block gets
        725  consistent gets
          0  physical reads
        568  redo size
     145854  bytes sent via SQL*Net to client
       7711  bytes received via SQL*Net from client
        668  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
      10001  rows processed

SQL> set autot off
SQL> delete test where object_id=50;

已删除10001行。

SQL> commit;

提交完成。

SQL> set autot trace
SQL> select * from test where object_id=50;

未选定行


执行计划
----------------------------------------------------------
Plan hash value: 1357081020

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     3 |   384 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TEST |     3 |   384 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

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

   1 - filter("OBJECT_ID"=50)

Note
-----
   - outline "OL" used for this statement


统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         53  consistent gets
          0  physical reads
          0  redo size
        992  bytes sent via SQL*Net to client
        374  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed

SQL>
SQL> alter system set use_stored_outlines=false;

系统已更改。

SQL> select * from test where object_id=50;

未选定行


执行计划
----------------------------------------------------------
Plan hash value: 3945961961

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

------

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

     |

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

------

|   0 | SELECT STATEMENT            |        |     1 |   128 |     1   (0)| 00:0

0:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| TEST   |     1 |   128 |     1   (0)| 00:0

0:01 |

|*  2 |   INDEX RANGE SCAN          | I_TEST |     1 |       |     1   (0)| 00:0

0:01 |

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

------


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

   2 - access("OBJECT_ID"=50)

Note
-----
   - dynamic sampling used for this statement


统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         31  consistent gets
          0  physical reads
          0  redo size
        992  bytes sent via SQL*Net to client
        374  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed

SQL>




你可能感兴趣的:(Outline)