设为首页 加入收藏

TOP

基于RULE的优化器(学习笔记)(一)
2015-07-24 11:36:21 来源: 作者: 【 】 浏览:15
Tags:基于 RULE 优化 学习 笔记

?

1.1 基于RULE的优化器

(1) CBO

(2)RBO

和CBO相比,RBO是有其明显权限的。在使用RBO的情况下,执行计划一旦出了问题,很难对其做调整。另外,如果使用了RBO则目标SQL的写法,甚至是目标SQL中所涉及的各个对象在该SQL文本中出现的先后顺序都可能影响RBO执行计划的选择我,更糟糕的是,Oracle数据库中很好的特性、功能不能再RBO中使用因为他们不能被RBO锁支持。

?

只要出现如下情形之一,那么即便修改了优化器模式或者使用了RULE Hnint,Oracle依然不会使用RBO(而是强制使用CBO)。

(1) 目标SQL中设计的对此昂有IOT(indexOrganized Table)。

(2) 目标SQL中设计的对象有分区表。

(3) 使用了平行查询或者并行DML。

(4) 使用了星形连接

(5) 使用了hash连接

(6) 使用了索引快速全扫描

(7) 使用了函数索引

(8) …...

这种情况下我们是很难对RBO选择的执行计划做调整的,其中一个十分关键的原因是不能使用hint。因为如果在目标SQL中使用了Hint,就意味着自动启动了CBO,即Oracle会以CBO来解析Hint的目标SQL。这里仅有两个例外,就是RULE Hint和SRIVING_SITE Hint,他可以在RBO下使用并且不自动启用CBO。

?

那么是不是在使用RBO的情况下就没有办法对执行计划进行调整了呢??

当然不是这样,只是这种情况下我们的调整手段非常有限。其中的一种可行的方法就是等价改写目标SQL,比如在目标SQL的where条件中对NUMBER或者DATE类型的列上加上0(如果是varchar2或者char类型,可以加上一个空字符,例如||’’),这样就可以让原本可以走的索引现在走不了。对于包含多表连接的目标sql而言,这种改变甚至可以影响表连接的顺序,进而就可以实现在使用RBO的情况下对该目标SQL的执行计划作出调整的目的。

?

?

但是如果出现了两条或者两条以上的等级值相同的执行路径的情况,那么RBO此时该如何选择呢?很简单,此时RBO会依据目标SQL中所涉及的相关对象在数据字典缓存(Data Dictionary cache)中的缓存顺序和目标SQL中所涉及的各个对象在目标SQL文本中出现的先后顺序来综合判断。这也就意味着我们还可以通过调整相关对象在数据字典中的缓存顺序,改变目标SQL中所涉及的各个对象在该SQL文本中出现的先后顺序来调整其执行计划。

?

实验:使用RBO的情况下,对目标SQL的执行计划调整。

?

?

create table emp_temp as select * from  emp;
 
create index idx_mgr_temp on emp_temp(mgr);
 
create index idx_deptno_temp on emp_temp(deptno);
 
 
select * from emp_temp where  mgr>100 and deptno>100;

?

?

###在当前session中配置优化器模式为RULE

?

alter session set optimizer_mode='RULE';

?

SET AUTOT TRACE EXP

?

\

?

假如我们发现走索引IDX_DEPTNO_TEMP不如走索引IDX_MGR_TEMP的执行效率高,或者我们想让RBO走索引IDX__MGR_TEMP,那么我们该如何让做??

?

可以加一个0不让它走索引:

?

?

Select * from  emp_temp where mgr>100 anddeptno+0>100;
 
08:28:11 scott@felix SQL>Select * from  emp_temp where mgr>100 anddeptno+0>100;
 
no rows selected
 
 
Execution Plan
----------------------------------------------------------
Plan hash value: 2973289657
 
----------------------------------------------------
| Id  |Operation                   | Name         |
----------------------------------------------------
|   0 |SELECT STATEMENT            |              |
|*  1 |  TABLE ACCESS BY INDEX ROWID| EMP_TEMP     |
|*  2 |   INDEX RANGE SCAN          | IDX_MGR_TEMP |
----------------------------------------------------
 
Predicate Information (identified by operationid):
---------------------------------------------------
 
   1 -filter("DEPTNO"+0>100)
   2 -access("MGR">100)
 
Note
-----
   - rulebased optimizer used (consider using cbo)
 
 
Statistics
----------------------------------------------------------
         1  recursive calls
         0  db block gets
         2  consistent gets
         0  physical reads
         0  redo size
       799  bytes sent via SQL*Net toclient
       512  bytes received via SQL*Netfrom client
         1  SQL*Net roundtrips to/fromclient
         0  sorts (memory)
         0  sorts (disk)
         0  rows processed
 
09:58:53 scott@felix SQL>
 


?

我们可以看到已经改变了执行计划。

?

?

刚才我先创建索引IDX_MGR_TEMP,再创建索引IDX_DEPTNO_TEMP,所以IDX_MGR_TEMP先缓存,在缓存IDX_DEPTNO_TEMP这种情形下RBO选择的是走对索引IDX_DEPTNO_TEMP的索引范围扫,如果反过来呢??

先删除索引IDDX_MGR_TEMP

?

?

09:58:53 scott@felix SQL>DROP INDEXIDX_MGR_TEMP;
 
Index dropped.
再创建该索引:
 
10:15:20 scott@felix SQL>create indexidx_mgr_temp on emp_temp(mgr);
 
Index created.
 
 
10:16:05 scott@felix SQL>Select * from  emp_temp where mgr>100 and deptno>100;
 
no rows selected
 
 
Execution Plan
------------------------------------
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇归档模式下恢复没有备份的数据文件 下一篇(四)概率

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·哈希表 - 菜鸟教程 (2025-12-24 20:18:55)
·MySQL存储引擎InnoDB (2025-12-24 20:18:53)
·索引堆及其优化 - 菜 (2025-12-24 20:18:50)
·Shell 中各种括号的 (2025-12-24 19:50:39)
·Shell 变量 - 菜鸟教 (2025-12-24 19:50:37)