我是靠谱客的博主 细心小笼包,最近开发中收集的这篇文章主要介绍oracle12c局限性,1.1.2.4 CBO的局限性,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.1.2.4  CBO的局限性

CBO诞生的初衷是为了解决RBO的先天缺陷,并且随着Oracle数据库版本的不断进化,CBO也越来越智能,越来越强悍,但这并不意味着CBO就***无瑕,没有任何缺陷了。这个世界上并没有***的事情,CBO同样如此。

实际上,CBO的缺陷(或者说局限性)至少表现在如下几个方面。

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

CBO会默认目标SQL语句where条件中出现的各个列之间是独立的,没有关联关系,并且CBO会依据这个前提条件来计算组合可选择率、Cardinality,进而来估算成本并选择执行计划。但这种前提条件并不总是正确的,在实际的应用中,目标SQL的各列之间有关联关系的情况实际上并不罕见。在这种各列之间有关联关系的情况下,如果还用之前的计算方法来计算目标SQL语句整个where条件的组合可选择率,并用它来估算返回结果集的Cardinality的话,那么估算结果可能就会和实际结果有较大的偏差,导致CBO选错执行计划。

目前可以用来缓解上述问题所带来负面影响的方法是使用动态采样或者多列统计信息,但动态采样的准确性取决于采样数据的质量和采样数据的数量,而多列统计信息并不适用于多表之间有关联关系的情形,所以这两种解决方法都不能算是***的解决方案。关于动态采样和多列统计信息,我们会在的"5.7  动态采样"和"5.8  多列统计信息"中分别予以详细说明。

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

CBO会假设所有的目标SQL都是单独执行、并且是互不干扰的,但实际情况却完全不是这样。我们执行目标SQL时所需要访问的索引叶子块、数据块等可能由于之前执行的SQL而已经被缓存在Buffer Cache中,所以这次执行时也许不需要耗费物理I/O去相关的存储上读要访问的索引叶子块、数据块等,而只需要去Buffer Cache中读相关的缓存块就可以了。所以,如果此时CBO还是按照目标SQL是单独执行,不考虑缓存的方式去计算相关成本值的话,就可能会高估走相关索引的成本,进而可能会导致选错执行计划。

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

CBO对直方图统计信息的限制体现在如下两个方面。

(1)在Oracle 12c之前,Frequency类型的直方图所对应的Bucket的数量不能超过254,这样如果目标列的distinct值的数量超过254,Oracle就会使用Height Balanced类型的直方图。对于Height Balanced类型的直方图而言,因为Oracle不会记录所有的nonpopular value的值,所以在此情况下CBO选错执行计划的概率会比对应的直方图统计信息是Frequency类型的情形要高。

(2)在Oracle数据库里,如果针对文本型的字段收集直方图统计信息,则Oracle只会将该文本型字段的文本值的头32字节给取出来(实际上只取头15字节)并将其转换成一个浮点数,然后将该浮点数作为上述文本型字段的直方图统计信息存储在数据字典里。这种处理机制的先天缺陷就在于,对于那些超过32字节的文本型字段,只要对应记录的文本值的头32字节相同,Oracle在收集直方图统计信息的时候就会认为这些记录该字段的文本值是相同的,即使实际上它们并不相同。这种先天性的缺陷会直接影响CBO对相关文本型字段的可选择率及返回结果集的Cardinality的估算,进而就可能导致CBO选错执行计划。

我们会在第5章的"5.5.3 直方图"中对上述两个限制予以详细说明,这里不再赘述。

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

在解析多表关联的目标SQL时,虽然CBO会采取多种手段来避免漏选正确的执行计划,但是这种漏选往往难以完全避免。因为随着多表关联的目标SQL所包含表的数量的递增,各表之间可能的连接顺序会呈几何级数增长,即该SQL各种可能的执行路径的总数也会随之呈几何级数增长。

假设多表关联的目标SQL所包含表的数量为n,则该SQL各表之间可能的连接顺序的总数就是n!(n的阶乘)。这意味着包含10个表的目标SQL各表之间可能的连接顺序总数为3,628,800,包含15个表的目标SQL各表之间可能的连接顺序总数为1,307,674,368,000。

SQL>select 10*9*8*7*6*5*4*3*2*1 from dual;

10*9*8*7*6*5*4*3*2*1

--------------------

3628800

SQL>select 15*14*13*12*11*10*9*8*7*6*5*4*3*2*1 from dual;

15*14*13*12*11*10*9*8*7*6*5*4*

------------------------------

1307674368000

包含15个表的多表关联的目标SQL在实际的应用系统中并不罕见,显然CBO在处理这种类型的目标SQL时是不可能遍历其所有可能的情形的,否则解析该SQL的时间将会变得不可接受。

在Oracle 11gR2中,CBO在解析这种多表关联的目标SQL时,所考虑的各个表连接顺序的总和会受隐含参数_OPTIMIZER_MAX_PERMUTATIONS的限制,这意味着不管目标SQL在理论上有多少种可能的连接顺序,CBO至多只会考虑其中根据_OPTIMIZER_MAX_PERMUTATIONS计算出来的有限种可能。这同时也意味着只要该目标SQL正确的执行计划并不在上述有限种可能之中,则CBO一定会漏选正确的执行计划。

虽然有上述这些局限性,但是瑕不掩瑜,CBO毫无疑问是当前情形下Oracle中解析目标SQL的不二选择,并且我们完全有理由相信随着Oracle数据库版本不断的进化,CBO也会越来越完善。

【责任编辑:book TEL:(010)68476606】

点赞 0

最后

以上就是细心小笼包为你收集整理的oracle12c局限性,1.1.2.4 CBO的局限性的全部内容,希望文章能够帮你解决oracle12c局限性,1.1.2.4 CBO的局限性所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部