- 优化器的模式
优化器的模式用于决定在Oracle中解析目标SQL时所用优化器的类型,以及决定当使用CBO时计算成本值的侧重点,这里的“侧重点”是指当使用CBO来计算目标SQL各条执行路径的成本值时,计算成本值的方法会随着优化器模式的不同而不同。
在oracle数据库中,优化器的模式是由参数OPTIMIZER_MODE的值来决定的,OPTIMIZER_MODE的值可能是RULE,CHOOSE,FIRST_ROWS_n(n=1,10,100,1000),FIRST_ROWS或ALL_ROWS.
OPTIMIZER_MODE的各个可能值的含义为如下所示:
(1)RULE
RULE表示oracle将使用RBO来解析目标SQL,此时目标sql中所涉及的各个对象的统计信息对于RBO来说没有任何作用
(2)CHOOSE
CHOOSE是oracle 9i中OPTIMIZER_MODE的默认值,它表示oracle在解析目标sql时到达时使用RBO还是使用CBO取决于该SQL中所涉及的表对象是否有统计信息。具体的说,只要该SQL中所涉及的表对象中有一个统计信息,那么oracle在解析该sql时就会使用CBO;如果该SQL中所涉及的所有表对象均没有统计信息,那么此时oracle将会使用RBO。
(3)FIRST_ROWS_n(n=1,10,100,1000)
这里FIRST_ROWS_n(n=1,10,100,1000)可以是FIRST_ROWS_1,FIRST_ROWS_10,FIRST_100,FIRST_ROWS_100和FIRST_ROWS_1000中任意一个值,其含义是指当OPTIMIZER_MODE的值为FIRST_ROWS_n(n=1,10,100,1000)时,oracle会使用CBO来解析目标SQL,且此时在技术该SQL的各执行路径的成本值时侧重点在于以最快的响应速度返回头n(n=1,10,100,1000)条记录。
当OPTIMIZE_MODE的值为FIRST_ROWS_n(1,10,100,1000),Oracle会把那些能够以最快的响应速度返回头n(n=1,10,100,1000)条记录所对应的执行步骤的成本值修改成一个很小的值(远远小于默认情况下CBO对同样执行步骤所计算出的成本值)。这样Oracle就既没有违背CBO选取执行计划的总原则(成本值最小),同时又兼顾了FIRST_ROWS_n(n=1,10,100,1000)的含义。
(4)FIRST_ROWS
FIRST_ROWS是一个在oracle 9i中就已经过时的参数,它表示oracle在解析目标SQL时联合使用CBO和RBO,这里联合使用RBO和CBO的含义是指在大多数情况下,FIRST_ROWS还是会使用CBO来解析目标SQL,且此时CBO在计算该SQL的各条执行路径的成本值时侧重点在于以最快的响应速度返回头几条记录(类似于first_rows_n);但是,当出现了一些特殊情况时,FIRST_ROWS转而会使用RBO中的一条内置的规则来选取执行计划而不再考虑成本。比如当OPTIMIZER_MODE的值为first_rows时有一个内置的规则,就是如果oracle发现能用相关索引来避免排序,则oracle就会选择该索引对应的执行路径而不再考虑成本,这显然是不合理的。与之对应的,在optimizer_mode的值为first_rows的情形下,你会发现索引全扫描出现的概率比之前有所增加,这是因为走索引全扫描避免排序的缘故。
(5)ALL_ROWS
all_rows是oracle 10g以及后续oracle数据库版本中optimizer_mode的默认值,它表示oracle会使用CBO来解析目标sql,且此时CBO计算该sql的各条执行路径的成本值的侧重点在于最佳的吞吐量(即最小的系统I/O和CPU资源的消耗量)
实际上,成本的计算方法随着优化模式的不同而不同,主要体现在ALL_ROWS和FIRST_ROWS_n(n=1,10,100,1000)对成本值计算方法的影响上。当优化器模式为ALL_ROWS时,CBO计算成本的侧重点在于最佳吞吐量,当优化器模式为first_rows_n(n=1,10,100,1000)时,CBO计算成本侧重点会变以最快响应速度返回头n条记录。这意味同样的执行步骤,在优化器模式为all_rows时和FIRST_ROW_n时CBO分别计算出来的成本值会存在巨大差异,这也就意味着优化器的模式对CBO计算成本(进而选择执行计划)有着决定性的影响。