ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 【OUTLINE】环境不满足OUTLINE记录的执行计划时会选择其他执行计划

【OUTLINE】环境不满足OUTLINE记录的执行计划时会选择其他执行计划

原创 Linux操作系统 作者:secooler 时间:2011-07-03 22:37:10 0 删除 编辑
  关于OUTLINE的使用方法请参见文章《【OUTLINE】使用Oracle Outline技术暂时锁定SQL的执行计划》(http://space.itpub.net/519536/viewspace-673010)。

  我们这里测试环境不具备OUTLINE中记录的执行计划时的执行效果。

1.环境准备
1)创建用户secooler,并授予适当权限,注意,用户需要具有create any outline权限
sys@ora10g> create tablespace tbs_secooler_d datafile '/oracle/ora10gR2/oradata/ora10g/tbs_secooler_d_01.dbf' size 10m autoextend on;

Tablespace created.

sys@ora10g> create user secooler identified by secooler default tablespace TBS_SECOOLER_D;

User created.

sys@ora10g> grant connect,resource to secooler;

Grant succeeded.

sys@ora10g> grant create any outline to secooler;

Grant succeeded.

2)在secooler用户中创建表T
sys@ora10g> conn secooler/secooler
Connected.
secooler@ora10g> create table t as select * from all_objects;

Table created.

secooler@ora10g> select count(*) from t;

  COUNT(*)
----------
      4370

3)在T表中创建索引
secooler@ora10g> create index i_t on t(object_id);

Index created.

4)此时的执行计划
secooler@ora10g> select * from t where OBJECT_ID=258;

Execution Plan
----------------------------------------------------------
Plan hash value: 2928007915

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

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

   2 - access("OBJECT_ID"=258)

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


2.创建OUTLINE
1)解锁OUTLN用户
sys@ora10g> conn / as sysdba
Connected.
sys@ora10g> alter user outln identified by outln account unlock;

User altered.

2)创建一个outline,取名叫做t_outln1,指定它的category名字为CATEGORY_T
outln@ora10g> conn secooler/secooler
Connected.
secooler@ora10g> create outline t_outln1 for category CATEGORY_T on select * from t where OBJECT_ID=258;

Outline created.

此时创建了一个访问表T时走索引的OUTLINE。

3.使用OUTLINE
1)调整当前session使用CATEGORY_T这个OUTLINE
secooler@ora10g> alter session set use_stored_outlines=CATEGORY_T;

Session altered.

(2)查看此时SQL的执行计划
secooler@ora10g> set autotrace traceonly explain;
secooler@ora10g> select * from t where OBJECT_ID=258;

Execution Plan
----------------------------------------------------------
Plan hash value: 2928007915

------------------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |    50 |  6400 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T    |    50 |  6400 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | I_T  |    20 |       |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------

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

   2 - access("OBJECT_ID"=258)

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


从执行计划上可以看到此时该SQL使用到了索引。

4.将T表索引删除测试使用OUTLINE效果
secooler@ora10g> drop index i_t;

Index dropped.

secooler@ora10g> alter session set use_stored_outlines=CATEGORY_T;

Session altered.

secooler@ora10g> set autotrace traceonly explain;
secooler@ora10g> select * from t where OBJECT_ID=258;

Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |    50 |  6400 |    15   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T    |    50 |  6400 |    15   (0)| 00:00:01 |
--------------------------------------------------------------------------

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

   1 - filter("OBJECT_ID"=258)

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


结论已经揭晓:
当表及索引信息不满足OUTLINE记录的执行计划时,Oracle并不会报错,而是走其他执行计划以便能够返回正确执行结果。

5.小结
OUTLINE并非“强制”按照记录的执行计划行事,当满足条件时会按照OUTLINE中的执行计划执行,当环境不满足时,也不会报错,SQL将选择其他的执行计划。

Good luck.

secooler
11.07.03

-- The End --

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/519536/viewspace-701310/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
Oracle ACE 总监,阿里云MVP,北京大学理学硕士,恩墨学院创始人,教育专家,中国区 Cloudera 首位官方授权大数据讲师,金牌培训专家,BDA大数据联盟创始人,OCM联盟创始人,ACCUG创始人、ACOUG核心专家,Blogger。

注册时间:2008-03-16

  • 博文量
    797
  • 访问量
    8093973