从上图可以看出,一条SQL进入ORACLE中,实际上经过解析会将各部分进行分离,每个分离的部分独立成为一
个查询块(query blocks),比如子查询会成为一个查询块,外部查询又是一个查询块,那么ORACLE优化器要做
的工作就是各查询块内部走什么样的访问路径更好(走索引、全表、分区?),其次就是各查询块之间应该走
什么样的JOIN方式以及JOIN顺序,最终计算出那种执行计划更好。
优化器的核心就是查询转换器、成本估算器以及执行计划生成器。
Transformer(查询转换器):
从图上可以看出,优化器的第一核心装置就是查询转换器,查询转换器的主要作用就是研究各种查询块之间的
关系,并从语法上甚至语义上给予SQL等价重写,重写后的SQL更容易被核心装置成本估算器和执行计划生成器
处理,从而利用统计信息生成最优执行计划。
查询转换器在优化器中有两种方式:启发式查询转换(基于规则)和基于COST的查询转换。启发式查询转换的一
般是比较简单的语句,基于成本的一般比较复杂,也就是说,符合基于规则的ORACLE不管什么情况下都会进行
查询转换,不符合的ORACLE可能考虑基于成本的查询转换。启发式查询转换历史悠久,问题较少,一般查询转
换过的效率比不经过查询转换的要高,而基于成本的查询转换,因其与CBO优化器紧密关联,在10G引入,内部
非常复杂,所以BUG也比较多,在日常优化过程中,各种疑难SQL,往往就出现在查询转换失败中,因为查询转
换一旦失败,Oracle就不能将原始SQL转换成结构更良好的SQL(更易于被优化器处理),显然可选择的执行路
径就要少很多,比如子查询不能UNNEST,那么,往往就是灾难的开始。其实,查询转换中Oracle做的最多的就
是将各种查询转换成JOIN方式,这样就可以利用各种高效的JOIN方法了,比如HASH JOIN。
查询转换共有30种以上的方式,下面列出一些常见启发式和基于COST的查询转换。
启发式查询转换(一系列的RULE):
很多启发式查询转换在RBO情况下就已经存在。常见的有:
评论