简答题 6.  什么是RBO和CBO?
【正确答案】Oracle数据库中优化器(Optimizer)是SQL分析和执行的优化工具,是Oracle数据库中内置的一个核心模块。优化器的目的就是为了得到目标SQL的执行计划。Oracle数据库里的优化器又分为RBO(rule-Based Optimizer,基于规则的优化器)和CBO(Cost-Based Optimizer,基于成本的优化器)这两种类型。从Oracle 10g开始,Oracle数据库默认都是基于CBO的优化方式。
   (1)RBO  RBO的执行机制非常简单,就是在优化器里面嵌入若干种规则,如果执行的SQL语句符合某个规则(Rank,共有1~15共15个等级),那么Oracle会按照规则(Rank)制定出相应的执行计划。由于RBO只是简单地去匹配Rank,所以它的执行计划在很多时候并不是最佳的。例如,某个表的其中一列数据分布非常不均匀,其中90%的数据内容是一样的,并且在这个字段上有索引。如果在目标SQL语句的谓词里有这个字段,那么RBO就会选择走索引。而这是一种非常慢的执行路径,因为Oracle要先访问索引块,在索引上找到相应的键值,然后按照键值上的ROWID再去访问表中的相应数据。其实,在这种情况下,选择全表扫描是最优的,但是RBO不会这么选择。RBO的缺点主要有:
   1)执行计划出了问题,很难对其做调整。
   2)执行计划会受目标SQL的写法、表在WHERE条件中出现的先后顺序等因素的影响。
   3)Oracle很多新特性不被RBO支持。
   4)制定出差的执行计划的概率比较大。
   5)忽略了SQL中表本身的统计信息情况。
   有的时候即使修改了优化器模式或者使用了RULE Hint,Oracle依然不会使用RBO(而是强制使用CBO),这些情况包括:
   1)当RULE和DRIVING_SITE联合使用时,RULE会失效。
   2)目标SQL中涉及的对象有IOT(Index Organized Table)。
   3)目标SQL中涉及的对象有分区表。
   4)使用了并行查询或者并行DML。
   5)使用了星型连接。
   6)使用了哈希连接。
   7)使用了索引快速全扫描。
   8)使用了函数索引。
   (2)CBO  从Oracle 7开始就引入了CBO。CBO是基于成本的优化器,它根据可用的访问路径、对象的统计信息、嵌入的Hint来选择一个成本最低的执行计划。优化器在使用CBO时,主要参照的是表、列及索引的统计信息。DBA可以通过设置初始化参数OPTIMIZER_MODE来决定到底使用哪个优化器,也可以用ALTER SESSION来改变当前SESSION中OPTIMIZER_MODE的值。除此之外在SQL中嵌入Hint可以指定具体某个SQL使用哪个优化器。OPTIMIZER_MODE选项有:ALL_ROWS、FIRST_ROWS_n(这里的n只能为1、10、100、1000)、FIRST_ROWS、CHOOSE和RULE,默认为ALL_ROWS。CBO包含的组件主要有:查询转换器(Query Transformer)、评估器(Estimator)和计划生成器(Plan Generator),如图所示。
   
【答案解析】