提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
基于规则的优化器(RBO)通过硬编码在Oracle数据库代码中的一系列固定的规则,来 决定目标SQL的执行计划。具体来说就是这样:Oracle会在代码里事先给各种类型的执行路径定一个等级, 一共有15个等级,从等级1到等级15。并且Oracle会认为等级值低的执行路径的执行效率会比等级值高的执 行效率要高,也就是说在RBO的眼里,等级1所对应的执行路径的执行效率最高,等级15所对应的执行路径 的执行效率最低。在决定目标SQL的执行计划时,如果可能的执行路径不止一条,则RBO就会从该SQL诸 多可能的执行路径中选择一条等级值最低的执行路径来作为其执行计划。
一、RBO中的驱动表
如果目标SQL出现了有两条或者两条以上的执行路径的等级值相同的情况,可以通 过改变目标SQL中所涉及的各个对象在该SQL文本中出现的先后顺序来调整该目标SQL的执行计划。这通 常适用于目标SQL中出现了多表连接的情形,在目标SQL出现了有两条或者两条以上的执行路径的等级值相 同的前提条件下,RBO会按照从右到左的顺序来决定谁是驱动表,谁是被驱动表,进而会据此来选择执行计 划,所以如果我们改变了目标SQL中所涉及的各个对象在该SQL文本中出现的先后顺序,也就改变了表连接 的驱动表和被驱动表,进而就调整了该SQL的执行计划。。
二、测试步骤
1.数据准备
代码如下(示例):
sqlplus scott/tiger
create table emp_temp as select * from emp
create table emp_temp1 as select * from emp
select t1.mgr,t2.deptno
? ? from emp_temp t1,emp_temp1 t2
? ?where t1.empno=t2.empno
? ?/
Execution Plan
----------------------------------------------------------
Plan hash value: 846513867
--------------------------------------------------------------------------------
| Id ?| Operation ? ? ? ? ?| Name ? ? ?| Rows ?| Bytes | Cost (%CPU)| Time ? ? |
--------------------------------------------------------------------------------
| ? 0 | SELECT STATEMENT ? | ? ? ? ? ? | ? ?14 | ? 210 | ? ? 6 ? (0)| 00:00:01 |
|* ?1 | ?HASH JOIN ? ? ? ? | ? ? ? ? ? | ? ?14 | ? 210 | ? ? 6 ? (0)| 00:00:01 |
| ? 2 | ? TABLE ACCESS FULL| EMP_TEMP ?| ? ?14 | ? 112 | ? ? 3 ? (0)| 00:00:01 |
| ? 3 | ? TABLE ACCESS FULL| EMP_TEMP1 | ? ?14 | ? ?98 | ? ? 3 ? (0)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
? ?1 - access("T1"."EMPNO"="T2"."EMPNO")
2.更换表的顺序看影响
将上面的SQL文本中的表顺序进行更换,验证
1 ?select t1.mgr, t2.deptno
? 2 ?from emp_temp1 t2,emp_temp t1
? 3* where t1.empno=t2.empno
SCOTT@erpdb> /
Execution Plan
----------------------------------------------------------
Plan hash value: 189864779
--------------------------------------------------------------------------------
| Id ?| Operation ? ? ? ? ?| Name ? ? ?| Rows ?| Bytes | Cost (%CPU)| Time ? ? |
--------------------------------------------------------------------------------
| ? 0 | SELECT STATEMENT ? | ? ? ? ? ? | ? ?14 | ? 210 | ? ? 6 ? (0)| 00:00:01 |
|* ?1 | ?HASH JOIN ? ? ? ? | ? ? ? ? ? | ? ?14 | ? 210 | ? ? 6 ? (0)| 00:00:01 |
| ? 2 | ? TABLE ACCESS FULL| EMP_TEMP1 | ? ?14 | ? ?98 | ? ? 3 ? (0)| 00:00:01 |
| ? 3 | ? TABLE ACCESS FULL| EMP_TEMP ?| ? ?14 | ? 112 | ? ? 3 ? (0)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
? ?1 - access("T1"."EMPNO"="T2"."EMPNO")
发现sql文本中表的顺序更换后,在rbo中的驱动表也成了最右侧的表。
总结
当目 标SQL有两条或者两条以上的执行路径的等级值相同时,我们确实可以通过改变目标SQL中所涉及的各个对 象在该SQL文本中出现的先后顺序来影响RBO对于其执行计划的选择。
注意,这种位置的先后顺序对于目标SQL执行计划的影响是有前提条件的,那就是仅凭各条执行路径等 级值的大小RBO难以选择执行计划,也就是说该目标SQL 一定有两条或者两条以上执行路径的等级值相同。 换句话说,如果RBO仅凭各条执行路径等级值的大小就可以选择目标SQL的执行计划,那么无论怎么调整 相关对象在该SQL的SQL文本中的位置,对于该SQL最终的执行计划都不会有任何影响。
|