虽然说oracle的RBO已经被淘汰了,但是为了整个优化知识的完整性,还是来看看历史上RBO是如何来运作的。
下面是oracle选择RBO优化产生的SQL的执行计划中表的扫描方式(table access)和RBO规则的优先顺序以及oracle在这条规则中使用什么方式来执行语句。,共15条:
优先顺序
扫描方式
使用情况
语句执行方式
1
Single Row by Rowid
在where语句中使用rowid,在应用中应该是不会有这种情况(在测试和学习中有时会用到),而且用rowid应该都是返回单行的。
oracle使用rowid来直接获取数据
2
Single Row by Cluster Join
如果联接的两表在同一簇中,并且在where中使用AND限定返回的是单行就使用这个access。
oracle使用的是nested loop
3

Single Row by Hash Cluster Key with Unique or Primary Key

在where限定条件中使用hash簇键的所有列,并且保证返回的是单行(这也是必然的,因为用作hash簇的键值的所有列一定是主键或者是唯一的)就是用这个access
oracle对指定的值做hash运算后和hash键值进行匹配。
4
Single Row by Unique or Primary Key
在where限定条件中使用主键或者唯一键,也必然是返回单行的。
oracle在主键或者唯一键上进行唯一扫描.
5
Clustered Join
同2,但不必是单行。
同2
6
Hash Cluster Key
同3,但不必是单行。
同3
7
Indexed Cluster Key
在where限定中使用索引簇键的所有列
oracle在主键或者唯一键上进行唯一扫描来获取所在行rowid,然后根据rowid来获取数据。由于簇中键值相同的所有行都是存储在一起的,所以只需要一个rowid就可以获得所有的数据。
8
Composite Index
在where限定中使用组合索引的所有列
oracle进行索引扫描获得所有指定行的rowid,然后根据rowid获取数据。(range scan)
9
Single-Column Indexes
在where限定中使用单列的索引
oracle对索引进行range scan获得所有指定行的rowid,然后根据rowid获取数据。如果在限定中使用多列都有单行索引,则oracle将这些索引融合起来。oracle最多融合5列索引,如果超过5列,则oracle融合前5列索引,然后对后面的结果逐行比对。
10
Bounded Range Search on Indexed Columns
在where限定中使用单列索引列或者组合索引中自首列开始且连续的部分列,并且在限定时同时指定最大最小值,例如:

   = 

 >= AND <=
 BETWEEN
 LIKE
oracle对索引进行range scan获得所有指定行的rowid,然后根据rowid获取数据
11
Unbounded Range Search on Indexed Columns
在where限定中使用单列索引列或者组合索引中自首列开始且连续的部分列,并且在限定时只指定最大或最小值中的一个,例如:

   >=

<= 
oracle对索引进行range scan获得所有指定行的rowid,然后根据rowid获取数据
12
Sort Merge Join
普通联接
oracle使用sort merge join或者nested loops
13
MAX or MIN of Indexed Column
在查询中对单列索引列或者组合索引中自首列开始且连续的部分列使用MAX或者MIN函数,并且查询中不包含其他表达式,没有where限定和group by语句
oracle对索引进行full scan来获取最大或者最小值,由于只需要这个值,所以oracle不用再根据值去表中获取数据。
14
ORDER BY on Indexed Column
在排序中使用单列索引列或者组合索引中自首列开始且连续的部分列,并且保证在order by中的列不能全为null,NLS_SORT参数 设为BINARY。
oracle对索引进行range scan获得所有有序的rowid,然后根据rowid获取有序的数据
15
Full Table Scan
任意情况
 
这是对RBO的15个规则进行了简单的描述,更深层次的原理要待以后的说明(比如index scan的方式)。可以看到,在RBO中全表扫描是排在最后的,也就是说只要能用索引,RBO一定会选择索引,即使有的时候全表扫描的效率会更高(例如第一个例子)。