ORACLE数据库SQL优化--->基于成本的优化器

        Oracle有两种优化器:RBO和CBO。 RBO的最大的问题在于它是靠硬编码在ORACLE数据库代码中的一系列规定的规则来决定目标SQL的执行计划的,而并没有考虑目标SQL中所涉及的对象的时间数据量,实际数据分布情况,这样一旦规定规则并不适用于该SQL中所涉及的实际对象时,RBO根据规定规则产生的执行计划就很可能不是当前情况下的最优执行计划了。

        下面我们来看如下的例子:

 select * from EMP_TEMP where manager_id=100;

假设在EMP_TEMP的manager_id上事先有名为IDX_MGR_TEMP的单键值B数索引,如果我们用的是RBO,则不管EMP_TEMP的数据量多大,也不管MANAGER_ID的数据分布如何,ORACLE执行的时候始终会选择做对IDX_MGR_TEMP的范围索引扫描,并回表取得EMP_TEMP中的记录。ORACLE是不会选择全表扫描EMP_TEMP表的,因为对于RBO而言,全表扫描的等级值要高于索引范围扫描值的等级值。

RBO的这种选择在表EMP_TEMP的数据量不大,而且满足manager_id=10的条件的记录少的情况下是影响不大的,如果表EMP_TEMP的数据量非常大,例如1000万条记录,

而且这1000万条记录的MANAGER_ID的值都是100,在这种极端的情况下,如果是RBO,显然它任然用IDX_MGR_TEMP索引范围扫描,这个时候性能肯定是很差的。因为相当于以单块顺序扫描所有的1000万行索引,然后再回表1000万次。显然没有使用多块以全表扫描方式直接扫描表EMP_TEMP的执行效率高。所以为了解决RBO的这个先天的缺陷,从ORACLE 7开始,ORACLE就引入了CBO。CBO在选择目标SQL的执行计划时,是用执行成本作为判断原则的。CBO会从目标SQL诸多可能的执行路径中选择一条成本值最小的执行路径作为其执行计划,各条执行路径的成本是根据目标SQL语句所涉及的表,索引,列等相关对象的统计信息计算出来的。这些信息存储在ORACLE的数据库的数据字典里,且从多个维度描述了ORACLE数据库里相关对象的实际数据量,实际数据分布等详细信息。

NOTE:ORACLE在对一条执行路径计算成本时,并不一定从头到尾完整计算完,只是要ORACLE在计算过程中发现算出来的部分成本值已经大于之前保存下来的到目前为止的最小成本值,就会马上终止对当前执行路径成本值的计算,并转而开始计算下一条新的执行路径的成本。这个过程会一直持续下去,直到目标SQL的给各个可能的执行路径全部计算完毕或已经达到预先定义好的待计算的执行路径数量的阀值。 

RBO是根据硬编码在ORACLE数据库中来决定目标SQL的执行计划的,并没有考虑目标SQL所所涉及的对象的实际数据量,实际分布情况等。而CBO则恰恰相反,它会根据目标SQL的相关的对象的实际数据量,实际数据分布情况的统计信息来决定其执行计划,即意味着CBO是随着目标SQL中所涉及的对象的统计信息的变化而变化的。这就意味着只有统计信息相对准确,则用CBO来解析目标SQL会比同等条件下的RBO来解析得到正确执行计划的概率要高。

当然CBO并不是完美的,它的缺陷主要表现在:

1,CBO会默认目标SQL语句的WHERE条件中出现的各个列之间是独立的,没有关系的。

2,CBO会假设所有的目标SQL都是单独执行的,并且互不干扰。

3,CBO对直方图统计信息有诸多限制。

4,CBO在解析多个表关联的目标SQL时,可能会漏掉正确的执行计划。

 

没有更多推荐了,返回首页