CBO基础概念

CBO基础概念

CBO:评估 I/O,CPU,网络(DBLINK)等消耗的资源成本得出

一、cardinality

cardinality:集合中包含的记录数。实际CBO评估目标SQL执行具体步骤的记录数,cardinality和成本是相关的,cardinality越大,执行步骤中的成本就越大

二、Selectivity

Selectivity :谓词的过滤条件返回的结果的行数占未加谓词过滤条件的行数

公式:=

范围0-1,值越小,说明 选择性越好 返回的cardinality 越小;值越大,选择性越差,返回的cardinality 越大。

未加任何谓词条件结果集: original cardinality,增加谓词条件为:computed cardinality。

computed cardinality=original cardinality*selectivity

在列上没有NULL或者直方图的情况下,selectivity取值

SELECTIVITY=

NUM_DISTINCT :表示为列中不同值的个数

三、transitivity(可传递性)

CBO会对现有的sql语句做等价转换,谓词条件、字段连接



优化器基础概念

一、优化类型:RBO和CBO

(一)、RBO

RBO基于规则的优化器access paths优先级:

  • RBO Path 1: Single Row by Rowid
  • RBO Path 2: Single Row by Cluster Join
  • RBO Path 3: Single Row by Hash Cluster Key with Unique or Primary Key
  • RBO Path 4: Single Row by Unique or Primary Key
  • RBO Path 5: Clustered Join
  • RBO Path 6: Hash Cluster Key
  • RBO Path 7: Indexed Cluster Key
  • RBO Path 8: Composite Index
  • RBO Path 9: Single-Column Indexes
  • RBO Path 10: Bounded Range Search on Indexed Columns
  • RBO Path 11: Unbounded Range Search on Indexed Columns
  • RBO Path 12: Sort Merge Join
  • RBO Path 13: MAX or MIN of Indexed Column
  • RBO Path 14: ORDER BY on Indexed Column
  • RBO Path 15: Full Table Scan

注意在不违反如上优先级的前提下,若有2个优化级一样的索引可用,则RBO会选择晚建的那个索引, 解决方法是重建你想要让RBO使用的那个索引,或者使用CBO……..

(二)、optimizer_mode :优化器的模式

1、RULE:使用rbo的规则

2、CHOOSE:9i中默认值,SQL语句全部的对象中无统计信息,使用RBO,其他使用CBO

3、FIRST_ROWS_n(n=1,10,100,1000):CBO会把哪些能够最快响应速度返回的成本设置为很小的值

4、ALL_ROWS:oracle10g 以后的默认值,会使用CBO来解析SQL,计算各个执行路径中的成本值最佳的吞吐量(最小的I/O和CPU资源)



二、结果集

执行计划中row,CBO评估的cardinality



三、访问数据的方法

(一)、访问表的方法:全表扫描和rowid访问

全表扫描:从高水位线下全部数据块读取,DELETE不会下降高水位线

ROWID访问:通过物理存储地址直接访问,rowid是个伪列,但是他能快速的定位的数据文件、块、行

[email protected]> select empno,rowid ,dbms_rowid.rowid_relative_fno(rowid)||‘_‘||dbms_rowid.rowid_block_number(rowid)||‘_‘||dbms_rowid.rowid_row_number(rowid) location_row from emp;

     EMPNO ROWID              LOCATION_ROW
---------- ------------------ ------------------------------
      7369 AAASZHAAEAAAACXAAA 4_151_0
      7499 AAASZHAAEAAAACXAAB 4_151_1
      7521 AAASZHAAEAAAACXAAC 4_151_2
      7566 AAASZHAAEAAAACXAAD 4_151_3
      7654 AAASZHAAEAAAACXAAE 4_151_4
      7698 AAASZHAAEAAAACXAAF 4_151_5
      7782 AAASZHAAEAAAACXAAG 4_151_6
      7788 AAASZHAAEAAAACXAAH 4_151_7
      7839 AAASZHAAEAAAACXAAI 4_151_8
      7844 AAASZHAAEAAAACXAAJ 4_151_9
      7876 AAASZHAAEAAAACXAAK 4_151_10
      7900 AAASZHAAEAAAACXAAL 4_151_11
      7902 AAASZHAAEAAAACXAAM 4_151_12
      7934 AAASZHAAEAAAACXAAN 4_151_13

(二)、索引访问

索引访问的成本:一部分时访问相关的B树索引的成本,另一个成本是回表的成本(根据索引中的rowid)

1、索引唯一性扫描(index unique scan):建立是唯一索引,能建立唯一索引的一定要建立唯一索引

2、索引范围扫描(index range scan):谓词条件中>、<等

3、索引全扫描(index full scan):扫描目标索引中所有的块的所有索引行。从最左的叶子节点读到底,因为叶子是一个双向链表

  • 索引全扫描的执行结果是有有序的,并且是按照该索引的索引键值列来排序,这也意味走索引全扫描能够既达到排序的效果,又同时避免了对该索引的索引键值列的真正的排序操作。
  • 索引全扫描时有序的就决定了不能够并行执行,索引全扫描时单块读
  • oracle中能做索引全扫描的前提条件是目标索引至少有一个索引键值列的属性是NOT NULL

4、索引快速全扫描(INDEX FAST FULL SCAN)

索引全扫描类似,读取所有叶子块的索引行

与全索引扫描不同点

  • 索引快速全扫描只适用于CBO
  • 索引快速全扫描可以使用多块读,也可以并行执行
  • 索引快速全扫描的执行结果不一定是有序的

5、索引跳跃式扫描(INDEX SKIP SCAN)

适用复合B数索引,谓词中的过滤条件不是以索引前导列。

只是对前导列做distinct:如create index ind_1 ON emp(job,empno)

Select * from emp where empno=7499

如果job有两个CLERK,SALESMAN

等同的语句

Select * from emp where job=‘CLERK‘ AND empno=7499
UNION ALL
Select * from emp where job=‘SALESMAN‘ AND empno=7499

oracle中的索引跳跃式扫描仅仅适用那些目标索引前导列的distinct值数量较少、后续非前导列的可选择性又非常好的情形,因为索引跳跃式扫描的执行效率一定会随着目标索引前导列的distinct值数量的递增而递减



四、表连接

(一)、表连接顺序

不管目标SQL中有多少个表做表连接,ORACLE在实际执行都是先做两两做表连接,在依次执行这样的两两表连接过程,直到目标SQL中所有表都已经连接完毕。

表连接很重要的是驱动表(outer table)和被驱动表(inner table)。

(二)、表连接方法

  • 嵌套循环连接(nested loop)

1、如果驱动表所对应的驱动结果集的记录数较少,同时在被驱动表的连接列上又存在唯一性索引(或者在被驱动表的连接列上存在选择性很好的非唯一性索引),那么此时使用嵌套循环连接的执行效率非常高。

2、大表也可以作为驱动表,关键看大表的谓词条件是否可以把驱动表的结果集的数据量下降下来

  • 哈希连接(hash join)

1、哈希连接不一定会排序,或者说大多数情况下都不需要排序

2、哈希连接的驱动表所对应的连接列的可选择性应尽可能好,因为这个可选择性会影响对应hash bucket中的记录数,而hash bucket中的记录数又会直接影响从该hash bucket中查询匹配记录的记录。如果一个hash bucket里所包含的记录数过多,则可能或严重降低所对应哈希连接的执行效率,此时典型的表现就是该哈希连接执行了很多时间都没有结束,数据库所在数据库服务器上的CPU占用率很高,但目标SQL所消耗的逻辑读却很低,因为此时大部分时间都耗费在了遍历上述Hash Bucket里的所有记录上,而遍历Hash Bucket里的记录这个动作发生在PGA的工作区里,所以不耗费逻辑读。

3、哈希连接只适用于CBO,它也只能用于等值连接条件(即使是哈希反连接,Oracle实际上也是讲其转换成了等价的等值连接)。

4、哈希连接很适合小表和大表之间做连接且连接结果集的记录数较多的情形,特别是在小表的连接列的可选择性非常好的情况下,这时候哈希连接的执行时间就可以近似看作和全表扫描那个大表所耗费的时间相当。

5、当两个表做哈希连接时,如果在施加目标SQL中指定的谓词条件(如果有的话)后得到的数据量较小的那个结果集所对应的hash table、 能够完全容纳在内存中(PGA的工作区),则此时的哈希连接的执行效率会非常高

  • 排序合并连接(merge jion)

1、通常情况下,排序合并连接的执行效率会远不如哈希连接,但前者的使用范围更广,因为哈希连接通常只能用于等值连接条件,而排序合并连接还能用于其他连接条件(<,<=,>,>=)

2、通常情况下,排序合并连接并不适合OLTP类型的系统,器本质原因是因为对于OLTP类型的系统而言,排序很昂贵的操作,当然,如果能避免排序操作,那么即使是OLTP类型的系统,也还是可以使用排序合并连接的。

3、排序合并连接并不存在驱动表的概念

  • 笛卡尔积连接(Cartesian join)

1、无任何连接条件,在执行计划中有cartesian,通常来说,有笛卡尔积,sql语句是有问题的

(三)、表连接的类型

1、内连接(Inner JOIN)

--使用=
select * from emp a join dept b on a.deptno=b.deptno
--join
select * from emp a join dept b on a.deptno=b.deptno

2、外连接(outer join)

左连接
--使用(+)
select * from emp a,dept b where a.deptno=b.deptno(+)
--使用left join

select * from emp a left outer join dept b on a.deptno=b.deptno

右连接
--使用(+)
select * from emp a,dept b where a.deptno(+)=b.deptno
--使用left join
select * from emp a right outer join dept b on a.deptno=b.deptno

外连接的驱动表以(+)对面的表,如以上左连接,驱动表为a,右连接的驱动表为b

3、反连接(anti join)

连接中not in、not exists 、<>

sql A:select * from emp a WHERE A.DEPTNO NOT  IN (SELECT DEPTNO FROM dept b where a.deptno=b.deptno)

sql B:select * from emp a WHERE NOT EXISTS (SELECT 1 FROM dept b where a.deptno=b.deptno)

sql C:select * from emp a WHERE A.DEPTNO <> all (SELECT DEPTNO FROM dept b where a.deptno=b.deptno)

4、半连接(semi join)

连接中用in,exists,any

select * from emp a WHERE A.DEPTNO   IN (SELECT DEPTNO FROM dept b where a.deptno=b.deptno)

select * from emp a WHERE  EXISTS (SELECT 1 FROM dept b where a.deptno=b.deptno)

select * from emp a WHERE A.DEPTNO =any(SELECT DEPTNO FROM dept b where a.deptno=b.deptno)

5、星形连接

在OLTP基本不会用到,在OLAP中用到

参考:崔华《基于ORACLE的SQL优化》

时间: 2024-10-20 03:18:17

CBO基础概念的相关文章

关系型数据库常用基础概念知识归纳

声明:我的文章都是只挑主要的写,次要细节太多,归纳就没意义了,同时归纳主要是给自己看的, 而且基本都是凭自己的一些记忆和理解即时写的.不一定对和全(但大多是一些需要理解的概念),请各位看管见谅! 数据库设计篇 1.范式 A.1范式,原子性,即列不可分 B.2范式,完全依赖,即有个主键唯一区分 C.3范式,不能传递依赖,即表中不能还有其他表的非主键信息 2.模型 A.概念模型,即ER图等 B.逻辑模型,即建逻辑表 C.物理模型,即生成物理表 事务 1.四大特性, A.原子,要么..要么.. B.隔

分布式学习——基础概念篇

概述 最近这段时间一直在看分布式有关的东西,但是关于分布式自己还是不能很好的理解,所以本文对分布式基础概念进行下学习. 分布式处理 首先先了解一下分布式处理,分布式处理和集中式处理正好是相反的的体系架构,集中传输集中到式处理顾名思义就是将所有的信息都一个统一的信息中心进行处理:分布式处理就是将不同地点的,或具有不同功能的,或拥有不同数据的多台计算机利用通信网络连接起来,让各个计算机各自承担同一个工作任务的不同部分,在控制中心的管理下,同时运行,共同完成同一个工作任务. 提到分布式处理就不能不提到

js基础--javascript基础概念之语法

掌握一门语言 必须先掌握它的语法! javascript 的语法和C.Java.Perl 的语法有些相似.但是比它们更加宽松. javascript 中的一切都是严格区分大小写的.例如变量: demo 和 Demo 两个变量是完全不同的. javascript 标示符,所谓标示符 是指 变量.函数.属性 的名字或函数的参数.标示符的格式是按照以下规则组合的一个或多个字符. 1.第一个字符必须是字母,下划线,或 $ 符号. 2.其他字符可以是字母.下划线.$ . 或数字. 注意 不能把关键字 保留

js基础--javascript基础概念之数组(二)

js基础--javascript基础概念之数组 数组栈方法 数组可以像栈一样.栈是一种先进后出的数据结构,最先添加的数据最后一个出来.栈方法添加数据也称为 推入  移除数据称为 弹出. js为数值栈方法提供了 push()   和  pop() ;  两个方法. push() push() 方法接受参数就是你要添加进入到数组的值.push()  方法会将他们逐一添加到数组的末尾  数组的length属性会跟着更新数据. *push(多个数组元素值) 返回的修改后的数组长度 var array =

js基础--javascript基础概念之数组

js基础--javascript基础概念之数组 在ECMAScript 中 ,数组是很常用的数据类型,js中的数组和其他很多语言的数组有明显的区别.js的数组可以保持任何类型的数值,一个数组中可以保存着多个不同类型的数值.js数组大小(长度)是可以调整的.可以随着数据的添加自动增长数组长度. 创建数组: 一.数组字面量 数组字面量由一对包含数组项的方括号[]表示. var array = [ 'kin', 'cheong', 'change', 'hello', 'haha', 'hi' ];

Linux基础概念-----环境变量

Shell 环境变量 Shell也是应用程序,工作与用户模式 变量类型 整形 浮点型 字符型 布尔型 bash变量类型 本地变量:仅对当前Shell有效 局部变量:仅对局部代码段有效(函数) 环境变量:expor VAR_NAME=Value,对当前Shell及子Shell有效 位置变量:$1;$2 .... 特殊变量:$?;$!;$$ .... 查看环境变量 printenv export 查看所有变量 set bash的引号 双引号:弱引用,可以实现变量替换: 单引号:强引用,不替换,而显示

Linux基础概念-----Linux I/O重定向 ,管道

标准输入:键盘 标准输出:显示器 错误输出:显示器 FD:文件描述符:让程序可以文件交互,并且便于内核识别文件,打开的每一个文件都有一个描述符 程序在和文件交互式,通过文件描述符来进行交互,而非文件名,文件名是方便用户分别文件. Linux一切皆文件,所以标准输入,标准输出都有各自的文件描述符 标准输入描述符:0 标准输出描述符:1 标准错误输出描述符:2 将其默认数据流改为其他设备:IO重定向 输出重定向 > 覆盖重定向 >> 追加重定向 /dev/null  黑洞 只针对当前Shel

js基础--javascript基础概念之语句(二)

js基础--javascript基础概念之语句(二)label,break,continue.. break .  continue 语句. break  continue 语句用于在循环中精确控制代码的执行,其中break语句会立即退出循环,执行循环后面的语句. continue 则退出循环后返回到再次进入循环中. 如: var num = 0; for(var i = 0; i<=100; i++){ if(i >= 10){ break; } num = i; } alert(num);

iOS开发OC基础:OC基础概念总结,OC面向对象的思想

一.什么是OOP: OOP(Object Oriented Programming):面向对象编程 二.面向对象和面向过程的区别: 面向过程编程:分析解决问题的步骤,实现函数,依次使用面向对象编程:分解问题组成的对象,协调对象间的联系和通信,解决问题. 面向过程是以事件为中心,关心的是完成这个事件的详细步骤:面向对象是以事物为中心,关心的是事物应该具备的功能,而完成一个事件只是事物所有功能里面的一个小功能(以过程为中心,以对象为中心) 三.类和对象 对象定义了解决问题的步骤中的行为,不刻意完成一