优化器的基础:
1、Oracle里的优化器:
优化器是Oracle数据库中内置的一个核心子系统,优化器的目的就是按照一定的判断原则来得到它认为目标sql在当前情形下最高效的执行路径,也就是说是为了得到目标sql的执行计划。
Oracle数据库的优化器分为:RBO和CBO两种类型:
RBO:基于规则的优化器(在得到sql执行计划时,RBO所用的判断原则为一组内置的规则)
CBO:基于成本的优化器(在得到sql执行计划时,CBO所用的判断原则为成本,它会从目标sql诸多可能的执行路线中选择成本值最小的一条来为其执行计划)
注意:
①:从Oracle10G开始,RBO已不再被Oracle支持,但是RBO的相关实现代码并么有从Oracle代码中移除,这也就是说在Oracle11GR2中依然可以通过修改优化器模式或使用rule hint来继续使用RBO;
②:RBO的缺点很多,其中Oracle很多很好的特性、功能均不能再RBO下使用,因为他们均不被RBO支持。
有如下情形的即使修改了优化器模式或使用了RULE hint Oracle依然不会使用RBO(而是会强制使用CBO)
①:目标sql中涉及的对象有IOT(index organized table)
②:目标sql中涉及的对象有分区表
③:使用了并行查询或者并行DML
④:使用了星型连接
⑤:使用了哈希链接
⑥:使用了索引快速全扫描
⑦:使用了函数索引
SQL> set autotrace traceonly ----开启sql跟踪,查看执行计划
1.1、基于规则的优化器-RBO
在当前会话中将优化器模式修改为RULE,表示当前的session中启用了RBO
SQL> alter session set optimizer_mode='RULE';
注意:在使用RBO的情况下可以通过等价改写目标sql(加0或者空字符串的方式)来调整该sql的执行计划
如:select * from emp_temp where mgr>100 and deptno+0>100; (deptno类型为number)
说明:
①:当目标sql有两条或者两条以上的执行计划的等级值相同时,我们确实可以通过调整相关对象在数据字典缓存中的缓存顺序来影响RBO对于其执行计划的选择;
②:如果RBO仅凭目标sql各条执行路径等级值的大小就可以选择出执行计划,那么无论怎么调整相关对象在该sql的sql文本中的位置,对于该sql最终的执行计划都不会有任何影响;
1.2、基于成本的优化器-CBO(从Oracle10G开始解析目标sql时默认使用CBO)
基于成本的优化器是指Oracle根据相关对象的统计信息计算出来的一个值,它实际上就是目标sql对应执行步骤的I/O CPU 和网络资源的消耗量的一个估算值;
2、CBO的一些基本概念:
①:cardinality(集的优势):是CBO特有的概念,它是指指定集合所包含的记录数;它实际上表示对目标sql的某个具体执行步骤的执行结果所包含记录数的估算。
②:可选择率:也是CBO特有的概念,它是指施加指定谓词条件后返回结果集的记录数占未施加任何谓词条件的原始结果集的记录数的比率。可选择率的取值范围是0~1,它的值越小,就表名可选择性越好,毫无疑问,可选择率为1时的可选择性是最差的;
③:可传递性:而是CBO特有的概念,其含义是指CBO可能会对原目标SQL做简单的等价改写,即在原目标SQL中加上根据sql现有的谓词条件推算出来的新谓词条件,这么做的目的是提供更多的执行路径给CBO做选择,进而增加得到更高效执行计划的可能性;
在Oracle里,可传递性又分为如下三种情形:
①:简单谓词传递
比如原目标sql的谓词条件是“t1.c1=t2.c1 and t1.c1=10”,则CBO可能会在这个谓词条件中额外地加上“t2.c1=10”,即被修改成
t1.c1=t2.c1 and t1.c1=10 and t2.c1=10
②:连接谓词传递
比如原来目标sql中的谓词条件是“t1.c1=t2.c1 and t2.c1=t3.c1”,则CBO可能会在这个谓词条件中额外地加上“t1.c1=t3.c1”,即被
修改成“t1.c1=t2.c1 and t2.c1=t3.c1 and t1.c1=t3.c1”
③:外连接谓词传递
比如原目标sql中的谓词条件是“t1.c1=t2.c1(+) and t1.c1=10”,则CBO可能会在这个谓词条件中额外加上“t2.c1(+)=10”,即被修改成
“t1.c1(+) and t1.c1=10 and t2.c1(+)=10”
3、CBO的局限性:
①:CBO会默认目标sql语句where条件中出现的各个列之间是独立的,没有关联关系
②:CBO会假设所有的目标sql都是单独执行的,并且互不干扰
③:CBO对直方图统计信息有诸多限制
④:CBO在解析多表关联的目标sql时,可能会漏选正确的执行计划
#######################################################################
4、优化器的模式
在Oracle数据库中,优化器的模式是由参数optimizer_mode的值来决定的,optimizer_mode的值可能是rule choose first_rows_n(n=1,10,100,1000) first_rows 或all_rows;
①:rule
rule表示Oracle将使用RBO来解析目标sql,此时目标sql中所涉及的各个对象的统计信息对于RBO来说将没有任何作用。
②:choose
choose是Oracle9i的optimizer_mode的默认值,它表示Oracle在解析目标sql时到底是使用RBO还是使用CBO取决于该sql中所涉及的表对象是否有统计信息。
(只要改sql中所涉及的表对象中有一个有统计信息,那么Oracle在解析该sql时就会使用CBO,如果该sql中所涉及的表对象均没有统计信息,那么Oracle就不会使用RBO)
③:first_rows_n(n=1,10,100,1000)
optimizer_mode可以是上面其中的任意一个值,其含义是指当optimizer_mode的值为first_rows_n(n=1,10,100,1000)时,Oracle会使用CBO来解析目标sql,且此时CBO在计算该sql的各条执行路径的成本值时的侧重点在于以最快的响应速度返回头n (n=1,10,100,1000)条记录。
④:first_rows
first_rows是一个在Oracle9i已经过时的参数,它表示Oracle在解析目标sql时会联合使用CBO和RBO。这里的联合是大多数情况下,first_rows还是会使用CBO来解析目标sql;
⑤:all_rows
all_rows是Oracle10G以后后续版本数据库版本中optimizer_mode的默认值,它表示Oracle会使用CBO来解析目标sql,且此时CBO在计算该sql的各条 执行路径的成本值时的侧重点在于最佳的吞吐量(即最小的系统I/O 和 CPU资源的消耗量);
《结果集》
结果集是指包含指定执行结果的集合,对于优化器而言(无论是RBO还是CBO)结果集和目标sql执行计划的执行步骤相对应,一个执行步骤所产生的执行结果就是该执行步骤所对应的输出结果集;