iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >CBO的相关原理 系列一
  • 610
分享到

CBO的相关原理 系列一

2024-04-02 19:04:59 610人浏览 安东尼
摘要

CBO的相关原理CBO在oracle7中被引入,基于数据对象的统计信息(包括数据集的行数,唯一值的个数等等)来计算执行计划的执行成本。随着版本的演化,CBO逐渐完善起来,在9i开始使用系统统计信息(syst

CBO的相关原理

CBO在oracle7中被引入,基于数据对象的统计信息(包括数据集的行数,唯一值的个数等等)来计算执行计划的执行成本。随着版本的演化,CBO逐渐完善起来,在9i开始使用系统统计信息(system statistics,系统统计信息的出现是为了估算sql在CPU方面的消耗)。但是CBO仍然存在一些缺陷,通过了解CBO的一些相关原理,其缺陷大家也就很容易理解了,从而也会明白,很多时候CBO所依赖的统计信息都收集的百分之百准确了,还是会选错执行计划的原因。

执行计划的选择

CBO在生成一条执行计划后,会计算其成本;然后和已经生成的执行计划中成本最低的进行比较。这种比较在以下条件满足其一就停止:

1.    所有执行计划都已经被计算过

查询块的join排列数超过了OPTIMIZER_MAX_PERMUTATioNS(10g及以后为_OPTIMIZER_MAX_PERMUTATIONS)参数指定的值。默认是2000.
我们可以做个简单的计算,比如下面这个SQL:
 CBO的相关原理 系列一

一个查询块中有7张表,这7张表做join可能的顺序有:

1.    a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7

2.    a1 -> a2 -> a3 -> a4 -> a5 -> a7 -> a6

3.    a1 -> a2 -> a3 -> a4 -> a6 -> a5 -> a7
......
所有可能的排列数就是7!=5040,远远超过了OPTIMIZER_MAX_PERMUTATIONS的默认值。那么这种情况下,CBO不会把所有可能的join顺序计算一遍。这就有可能错过了成本最低的执行计划。之所以这么设计是防止过多的对执行计划成本的比较导致花费在SQL解析的时间过长。

成本计算的基本概念

1 cardinality(基数)

cardinality指的是一个行源的结果集的行数。比如在下面这个查询中,返回的为emp表的所有行,基数就是表的行数14.
 CBO的相关原理 系列一
再比如:

 CBO的相关原理 系列一

其cardinality是emp表经过谓词过滤(job='CLERK')返回的行数4.

2 selectivity(选择率)

选择率,也叫选择性,和cardinality密切相关。选择率的计算公式如下:
 CBO的相关原理 系列一

比如emp表共有14行,empno是主键,那么每一个值出现的频率就是1/14.那么下面这条sql的过滤条件选择率就是1/14.
 CBO的相关原理 系列一

我们知道CBO在执行计划的某一步选择访问全表还是索引时会考虑到选择率,从上面的公式可以看出,要得出选择率需要知道两个数据。下面仍然以1.cardinality部分的例子,解释CBO如何根据统计信息来计算选择率。
 CBO的相关原理 系列一
 CBO的相关原理 系列一

可以看到这条sql实际返回4条,但是rows部分的值为3.3是怎么被算出来的呢?

首先,CBO从统计信息中获得emp表的总行数为14;然后根据job这一列上的唯一键值(num_distinct)得出该列上等值条件的选择率为1/5(即1/num_distinct,在没有直方图的情况下,CBO认为列值没有数据倾斜,数据分布都是均匀的,那么列中的每一个值出现的频率都是同样的1/num_distinct)。这样计算应该得到的结果集为141/5=2.8,CBO的算法中对该结果还要向上取整(ceil),即结果是ceil(141/5)=3.
打个比方,在一个黑色布袋里放有若干白球和黑球,在没有打开袋子去数的情况下,要猜测每个颜色的球各有多少个,只能先做一个假设它们的数量是差不多的。
可以预想,在一个有数据倾斜(即不同的唯一值对应的行数差异很大)的列上,继续使用这种算法,可能会产生错误的执行计划。
下面创建一个有数据倾斜的表
 CBO的相关原理 系列一
 CBO的相关原理 系列一

现在如果我们查询gender='M'的行的数据,显然如果在gender列如果有索引,访问索引获得rowid后再回表是最高效的,但是根据前面的解释,在收集了统计信息而没有收集直方图的情况下,CBO会认为gender='M'返回的数据量为全部数据量的50%,从而选择全表扫描。
 CBO的相关原理 系列一

可以看到rows对应的值65537,确实是表的总行数*50%(向上取整)。
在实际的应用场景里,表的过滤条件可能有多个,过滤条件之间有and或者or连接。这两种情况下的选择率的计算,和高中知识中计算概率的与或运算很相似。
首先对于条件之间使用and的情况:
比如:select ... from a where a.col1=value1 and a.col2=value2。这种情况下,CBO是如何计算选择率呢?我们在之前的例子上加一个过滤条件:
 CBO的相关原理 系列一
 CBO的相关原理 系列一

可以看到rows部分预估的是1,实际有2条数据。我们把两个过滤条件分别记为i和j,出现的频率记为P(i)和P(j),在没有多列统计信息的情况下,CBO认为i和j同时成立的频率就是P(i)P(j).根据前面的解释,我们知道P(i)=1/5,P(j)=1/3,那么P(i)P(j)=1/15.emp表的总行数为14,那么由这两个过滤条件产生的结果集为ceil(14*(1/15))=1.
对于2个以上过滤条件的情况,也有类似的算法。比如有过滤条件i1,i2,i3...,in,那么最终的选择率的算法为:
 CBO的相关原理 系列一

对于过滤条件之间是or的情况,算法为(涉及高中概率的知识):
 CBO的相关原理 系列一

可见如果当过滤条件过多时,选择率计算的结果很可能大大失真。
比如对于sql:
 CBO的相关原理 系列一

根据上面的公式算出来的选择率很可能非常接近于0,据此计算出来的cardinality接近于1.而实际上返回结果很可能会有多条。

3 Transitivity(传递性)

transitivity是指CBO对过滤或者连接条件做一些等价转换,使得原来仅仅作用在表A的过滤或者连接条件,可以作用在与A做JOIN的B表上。比如:
 CBO的相关原理 系列一

可以转换成:
 CBO的相关原理 系列一

对于这种转换,如果b表的col1列上有选择性较好的索引,CBO就可以选择访问索引。RBO模式下是不会做此转换的。
除了上面这种情况,还有join的传递:

 CBO的相关原理 系列一

转换为
 CBO的相关原理 系列一

CBO的缺陷

通过前面这些介绍,我们可以得出CBO存在的缺陷:

1.    对于复杂SQL,有可能会无法覆盖全部可能的执行计划,因此而忽略最佳的执行计划;

2.    在没有收集直方图的情况下,CBO认为列的值是均匀分布的,对于有数据倾斜的表,这种假设将大大失真;

3.    在没有多列统计信息和拓展统计信息的情况下,CBO认为列和列之间是孤立的,在SQL包含多个列的过滤条件或者表之间做join的情况下,计算的选择率很可能会失真。

我们常常听到说,用explain,autotrace等从plan table里获得执行计划是假的,或者rows等不准等说法,原因就在这里。但是oracle的厉害之处在于可以不断改进CBO,像上面也提到了,oracle推出了直方图,多列统计信息,拓展统计信息等技术来弥补原本算法的不足。这些技术的使用也将另起一文。
对于本文中有表述错误或者片面的地方,还请大家多多指出;还有解释不清的地方,也可以告诉我,在下一篇中做下解释。


您可能感兴趣的文档:

--结束END--

本文标题: CBO的相关原理 系列一

本文链接: https://www.lsjlt.com/news/41607.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PHP相关系列 - 优化你的PHP代码
    优化PHP代码是提高程序性能和效率的重要步骤。下面是一些优化PHP代码的常见方法:1. 减少数据库查询次数:尽量使用JOIN操作或者...
    99+
    2023-09-14
    PHP
  • Redis的慢日志相关底层原理
    这篇文章主要讲解了“Redis的慢日志相关底层原理”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Redis的慢日志相关底层原理”吧! 01、前言相...
    99+
    2024-04-02
  • 【数模系列】02_三大相关系数+Python代码
    文章目录 一、皮尔逊相关系数1、公式推导2、使用条件3、Python绘图 二、斯皮尔曼秩相关系数1、如何选择皮尔逊和斯皮尔曼 三、肯德尔秩相关系数 一、皮尔逊相关系数 在统计学中,...
    99+
    2023-09-18
    python
  • 批处理bat将txt文本第一列内容相同的行的最后一列的数字相加
    小弟不材,想了好几天没写出来,才来论坛求助,希望各位高手帮帮忙解下题 ,在此先谢谢各位了~ 比如,aaa.txt 内容如下 11111,20150430,10 11111,20150...
    99+
    2024-04-02
  • 网络原理(一)网络基础,包括IP ,网络相关的定义
    网络基础,包括IP ,网络相关的定义 网络基础冲突域广播域DNSNATNAPT 网络基础 以下图片是书上的网图。 什么是IP地址? IP地址(Internet Protocol Add...
    99+
    2023-09-12
    网络 tcp/ip php
  • 5G与WiFi6相爱相杀的关系
           近半年来,5G网络的消息层出不穷。5G商用牌照正式发放,三大运营商表示要在今年年底前至少覆盖40个城市,最新的中国5G网络招标结果等。在人们对5G展示最大热情的时候,WiFi6横空出世。...
    99+
    2023-06-03
  • 关于Kafka消息队列原理的总结
    目录Kafka消息队列原理Kafka的逻辑数据模型Kafka的分发策略Kafka的物理存储模型和查找数据的设计Kafka的持久化策略设计Kafka的节点间的数据一致性策略设计Kafk...
    99+
    2024-04-02
  • RAC 相关的等待及原因
    Wait events for Oracle RAC include the following categories: 1.Block-Related Wait Events 2.Message-Re...
    99+
    2024-04-02
  • Python如何根据相邻关系还原数组
    小编给大家分享一下Python如何根据相邻关系还原数组,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!题目描述这是 LeetCode 上的 1743. 从相邻元素对...
    99+
    2023-06-20
  • MySQL数据库锁机制的相关原理介绍
    这篇文章主要讲解了“MySQL数据库锁机制的相关原理介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MySQL数据库锁机制的相关原理介绍”吧!  不同于行...
    99+
    2024-04-02
  • Dubbo 系列JDK SPI 原理解析
    目录正文为什么要使用SPI?什么是 SPIJDK SPI 机制JDK SPI原理为什么不直接使用 JDK SPI正文 上一篇文章讲到了如何去找到 Dubbo 源码的调试入口,如果你...
    99+
    2023-02-24
    Dubbo JDK SPI原理 Dubbo JDK SPI
  • 一些关于Go程序错误处理的相关建议
    目录前言认识error自定义错误记得要实现error接口错误处理常犯的错误错误处理常犯的两个问题给错误附加上下文信息总结前言 Go的错误处理这块是日常被大家吐槽较多的地方,我在工作中...
    99+
    2024-04-02
  • CentOS管理相关系统是怎样应用的
    这篇文章将为大家详细讲解有关CentOS管理相关系统是怎样应用的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。CentOS管理系统的特性,既可作为高校计算机专业CentOS管理学习,也可以作...
    99+
    2023-06-16
  • react合成事件与原生事件的相关理解
    目录1. 原生事件 2. 合成事件 为什么react事件需要手动绑定this3. 原生与合成事件触发顺序4. 合成事件和原生事件混用 相关疑问:e.nativeEvent.stopP...
    99+
    2024-04-02
  • JVM内存区域划分相关原理详解
    JVM内存区域划分是指将JVM中的内存划分为不同的区域,每个区域有不同的用途和管理方式。JVM内存区域的划分主要有以下几个方面:1....
    99+
    2023-08-11
    JVM
  • Dubbo系列JDK SPI原理是什么
    这篇文章主要介绍“Dubbo系列JDK SPI原理是什么”,在日常操作中,相信很多人在Dubbo系列JDK SPI原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Dubbo系列JD...
    99+
    2023-07-05
  • Flutter与原生IOS(swift)交互系列之一
    先用Android Studio创建一个空的flutter工程作为演示 可以看到根目录下有一个名为ios的目录,这个就是ios的工程目录。 我们将它展开,发现下面有许多个文件 ...
    99+
    2023-08-31
    flutter ios Powered by 金山文档
  • Java游戏服务器系列之Netty相关知识总结
    目录一、简介二、Netty的应用场景三、异步和事件驱动性四、Netty核心组件五、总结一、简介 Java的底层API逐渐复杂,而开发者面对的开发场景需求也在逐渐增大。如果直接针对底层...
    99+
    2024-04-02
  • 如何理解Linux内核及其相关架构的依赖关系
    这篇文章主要介绍“如何理解Linux内核及其相关架构的依赖关系”,在日常操作中,相信很多人在如何理解Linux内核及其相关架构的依赖关系问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解Linux内核及其...
    99+
    2023-06-12
  • 夯实Java基础系列4:一文了解final关键字的特性、使用方法,以及实现原理
    本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看https://github.com/h3pl/Java-Tutorial喜欢的话麻烦点下Star哈文章首发于我的个人博客:www.how2pla...
    99+
    2023-06-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作