Oracle 基础篇 --- B树索引内部结构

内部结构

将B树索引转储成树状结构的形式而呈现出来:

alter session set events ‘immediate trace name treedump level INDEX_OBJECT_ID‘;

SQL> alter session set events ‘immediate trace name treedump level 126545‘;

Session altered.

[[email protected] trace]$ pwd
/home/oracle/app/oracle/diag/rdbms/tonytest/tonytest/trace
[[email protected] trace]$ vi tonytest_ora_5439.trc

----- begin tree dump
branch: 0x34000e3 54526179 (0: nrow: 444, level: 1)
   leaf: 0x34000e4 54526180 (-1: nrow: 393 rrow: 393)
   leaf: 0x34000e5 54526181 (0: nrow: 377 rrow: 377)
   leaf: 0x34000e6 54526182 (1: nrow: 378 rrow: 378)
   leaf: 0x34000e7 54526183 (2: nrow: 377 rrow: 377)
   leaf: 0x34000e8 54526184 (3: nrow: 377 rrow: 377)
   leaf: 0x34000e9 54526185 (4: nrow: 378 rrow: 378)
   leaf: 0x34000ea 54526186 (5: nrow: 379 rrow: 379)
   leaf: 0x34000eb 54526187 (6: nrow: 379 rrow: 379)
   leaf: 0x34000ec 54526188 (7: nrow: 379 rrow: 379)
…………………
----- end tree dump

  • 每一行的第一列表示节点类型>:branch表示分支节点(包括根节点),而leaf则表示叶子节点;
  • 第二列表示十六进制表示的节点的地址;
  • 第三列表示十进制表示的节点的地址;
  • 第四列表示相对于前一个节点的位置,根节点从0开始计算,其他分支节点和叶子节点从-1开始计算;
  • 第五列的nrow表示当前节点中所含有的索引条目的数量。比如我们可以看到根节点中含有的nrow为444,表示根节点中含有444个索引条目,分别指向444个分支节点;
  • 第六列中的rrow表示有效的索引条目(因为索引条目如果被删除,不会立即被清除出索引块中。所以nrow减rrow的数量就表示已经被删除的索引条目数量)的数量,比如对于第一个leaf来说,其rrow为393,也就是说该叶子节点中存放了393个可用索引条目,分别指向表emp3的393条记录。

转储一个索引节点

alter system dump datafile file# block block#;

select dbms_utility.data_block_address_file(54526179),
dbms_utility.data_block_address_block(54526179) from dual;

DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(54526179) DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(54526179)
---------------------------------------------- -----------------------------------------------
                                            13                                             227

SQL> alter system dump datafile 13 block 227;

System altered.

Branch block dump
=================
header address 140301252250188=0x7f9a6e4d4a4c
kdxcolev 1
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 443
kdxcofbo 914=0x392
kdxcofeo 2739=0xab3
kdxcoavs 1825
kdxbrlmc 54526180=0x34000e4
kdxbrsno 49
kdxbrbksz 8056
kdxbr2urrc 3
  • kdxcolev表示索引层级号,这里由于我们转储的是根节点,所以其层级号为1。对叶子节点来说该值为0;
  • kdxcolok表示该索引上是否正在发生修改块结构的事务;
  • kdxcoopc表示内部操作代码;
  • kdxconco表示索引条目中列的数量;
  • kdxcosdc表示索引结构发生变化的数量,当你修改表里的某个索引键值时,该值增加;
  • kdxconro表示当前索引节点中索引条目的数量,但是注意,不包括kdxbrlmc指针;
  • kdxcofbo表示当前索引节点中可用空间的起始点相对当前块的位移量;
  • kdxcofeo表示当前索引节点中可用空间的最尾端的相对当前块的位移量;
  • kdxcoavs表示当前索引块中的可用空间总量,也就是用kdxcofeo减去kdxcofbo得到的。
  • kdxbrlmc表示分支节点的地址,
  • kdxbrsno表示最后一个被修改的索引条目号,如果=0,表示该索引是新建的索引;
  • kdxbrbksz表示可用数据块的空间大小。实际从这里已经可以看到,即便是PCTFREE设置为0,也不能用足8192字节。
row#0[8043] dba: 54526181=0x34000e5
col 0; len 7; (7):  64 65 76 32 32 34 39
col 1; TERM
row#1[8030] dba: 54526182=0x34000e6
col 0; len 7; (7):  64 65 76 32 36 32 36
col 1; TERM
row#2[8017] dba: 54526183=0x34000e7
col 0; len 7; (7):  64 65 76 33 30 30 33
col 1; TERM
row#3[8005] dba: 54526184=0x34000e8
col 0; len 6; (6):  64 65 76 33 33 38
col 1; TERM

每个索引条目都指向一个分支节点。
col 1表示所链接的分支节点的地址,该值经过一定的转换以后实际就是row#所在行的dba的值。如果根节点下没有其他的分支节点,则col 1为TERM;
col 0表示该分支节点所链接的最小键值。

#索引高度为1
----- begin tree dump

*** 2015-07-10 07:05:03.971
branch: 0x34000e3 54526179 (0: nrow: 479, level: 1)
   leaf: 0x34000e4 54526180 (-1: nrow: 272 rrow: 272)
   leaf: 0x34004c9 54527177 (0: nrow: 272 rrow: 272)
   leaf: 0x34004d3 54527187 (1: nrow: 272 rrow: 272)
   leaf: 0x34004ab 54527147 (2: nrow: 272 rrow: 272)
   leaf: 0x34004af 54527151 (3: nrow: 272 rrow: 272)
.........
   leaf: 0x34004a9 54527145 (473: nrow: 420 rrow: 420)
   leaf: 0x34004ad 54527149 (474: nrow: 420 rrow: 420)
   leaf: 0x34004b1 54527153 (475: nrow: 420 rrow: 420)
   leaf: 0x34004b5 54527157 (476: nrow: 420 rrow: 420)
   leaf: 0x34004e2 54527202 (477: nrow: 96 rrow: 96)
----- end tree dump

#模拟插入数据,然后根节点分裂,索引高度为2
SQL> alter session set events ‘immediate trace name treedump level 126545‘;

Session altered.

----- begin tree dump
branch: 0x34000e3 54526179 (0: nrow: 3, level: 2)
   branch: 0x34005d7 54527447 (-1: nrow: 253, level: 1)
      leaf: 0x34000e4 54526180 (-1: nrow: 272 rrow: 272)
      leaf: 0x34005e1 54527457 (0: nrow: 272 rrow: 272)
      leaf: 0x34005f1 54527473 (1: nrow: 272 rrow: 272)
      leaf: 0x34005fa 54527482 (2: nrow: 272 rrow: 272)
      leaf: 0x34005fe 54527486 (3: nrow: 272 rrow: 272)
.........
      leaf: 0x3400779 54527865 (246: nrow: 272 rrow: 272)
      leaf: 0x3400766 54527846 (247: nrow: 272 rrow: 272)
      leaf: 0x340076a 54527850 (248: nrow: 310 rrow: 310)
      leaf: 0x340076d 54527853 (249: nrow: 379 rrow: 379)
      leaf: 0x34005b9 54527417 (250: nrow: 271 rrow: 271)
      leaf: 0x34005bd 54527421 (251: nrow: 272 rrow: 272)
   branch: 0x34007e2 54527970 (0: nrow: 256, level: 1)
      leaf: 0x34005a7 54527399 (-1: nrow: 272 rrow: 272)
      leaf: 0x34005a8 54527400 (0: nrow: 265 rrow: 265)
      leaf: 0x34005ac 54527404 (1: nrow: 272 rrow: 272)
      leaf: 0x3400597 54527383 (2: nrow: 471 rrow: 471)
      leaf: 0x3400582 54527362 (3: nrow: 271 rrow: 271)
      leaf: 0x3400586 54527366 (4: nrow: 267 rrow: 267)
.........
      leaf: 0x3400273 54526579 (249: nrow: 212 rrow: 212)
      leaf: 0x340022c 54526508 (250: nrow: 212 rrow: 212)
      leaf: 0x3400230 54526512 (251: nrow: 212 rrow: 212)
      leaf: 0x3400277 54526583 (252: nrow: 212 rrow: 212)
      leaf: 0x340027b 54526587 (253: nrow: 213 rrow: 213)
      leaf: 0x340027f 54526591 (254: nrow: 393 rrow: 393)
   branch: 0x34005da 54527450 (1: nrow: 278, level: 1)
      leaf: 0x34000ff 54526207 (-1: nrow: 213 rrow: 213)
      leaf: 0x3400246 54526534 (0: nrow: 212 rrow: 212)
      leaf: 0x3400240 54526528 (1: nrow: 212 rrow: 212)
      leaf: 0x3400244 54526532 (2: nrow: 212 rrow: 212)
      leaf: 0x3400266 54526566 (3: nrow: 212 rrow: 212)
      leaf: 0x340026a 54526570 (4: nrow: 212 rrow: 212)
.........
      leaf: 0x34004a5 54527141 (271: nrow: 420 rrow: 420)
      leaf: 0x34004a9 54527145 (272: nrow: 420 rrow: 420)
      leaf: 0x34004ad 54527149 (273: nrow: 420 rrow: 420)
      leaf: 0x34004b1 54527153 (274: nrow: 420 rrow: 420)
      leaf: 0x34004b5 54527157 (275: nrow: 420 rrow: 420)
      leaf: 0x34004e2 54527202 (276: nrow: 96 rrow: 96)
----- end tree dump

Branch block dump
=================
header address 140408996839500=0x7fb38461404c
kdxcolev 2
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 1
kdxconro 2
kdxcofbo 32=0x20
kdxcofeo 8030=0x1f5e
kdxcoavs 7998
kdxbrlmc 54527447=0x34005d7
kdxbrsno 0
kdxbrbksz 8056
kdxbr2urrc 3
row#0[8030] dba: 54527970=0x34007e2
col 0; len 3; (3):  64 65 76
col 1; len 6; (6):  03 40 06 dc 00 92
row#1[8045] dba: 54527450=0x34005da
col 0; len 5; (5):  71 61 33 33 39
col 1; TERM
----- end of branch block dump -----
End dump data blocks tsn: 19 file#: 13 minblk 227 maxblk 227


索引访问

当oracle需要访问索引里的某个索引条目时,oracle是如何找到该索引条目所在的数据块的呢?

当oracle进程需要访问数据文件里的数据块时,oracle会有两种类型的I/O操作方式:

  • 随机访问,每次读取一个数据块(通过等待事件“db file sequential read”体现出来)。
  • 顺序访问,每次读取多个数据块(通过等待事件“db file scattered read”体现出来)。

第一种方式则是访问索引里的数据块,而第二种方式的I/O操作属于全表扫描。这里顺带有一个问题,为何随机访问会对应到db file sequential read等待事件,而顺序访问则会对应到db file scattered read等待事件呢?这似乎反过来了,随机访问才应该是分散(scattered)的,而顺序访问才应该是顺序(sequential)的。其实,等待事件主要根据实际获取物理I/O块的方式来命名的,而不是根据其在I/O子系统的逻辑方式来命名的。下面对于如何获取索引数据块的方式中会对此进行说明。

我们看到前面对B树索引的体系结构的描述,可以知道其为一个树状的立体结构。其对应到数据文件里的

排列当然还是一个平面的形式,也就是像下面这样。因此,当oracle需要访问某个索引块的时候,势必会在这个结构上跳跃的移动。

/根/分支/分支/叶子/…/叶子/分支/叶子/叶子/…/叶子/分支/叶子/叶子/…/叶子/分支/…..

当oracle需要获得一个索引块时,首先从根节点开始,根据所要查找的键值,从而知道其所在的下一层的分支节点,然后访问下一层的分支节点,再次同样根据键值访问再下一层的分支节点,如此这般,最终访问到最底层的叶子节点。可以看出,其获得物理I/O块时,是一个接着一个,按照顺序,串行进行的。在获得最终物理块的过程中,我们不能同时读取多个块,因为我们在没有获得当前块的时候是不知道接下来应该访问哪个块的。因此,在索引上访问数据块时,会对应到db file sequential read等待事件,其根源在于我们是按照顺序从一个索引块跳到另一个索引块,从而找到最终的索引块的。

那么对于全表扫描来说,则不存在访问下一个块之前需要先访问上一个块的情况。全表扫描时,oracle知道要访问所有的数据块,因此唯一的问题就是尽可能高效的访问这些数据块。因此,这时oracle可以采用同步的方式,分几批,同时获取多个数据块。这几批的数据块在物理上可能是分散在表里的,因此其对应到db file scattered read等待事件。

时间: 2024-11-07 14:31:33

Oracle 基础篇 --- B树索引内部结构的相关文章

Oracle 基础篇 --- 索引

第四. 索引 4.1 定义 索引是与表关联的可选结构.通过创建索引可提高数据更新和检索的性能.Oracle 索引提供到数据行的直接访问路径. 可以对表的一个或多个列创建索引.创建索引后,Oracle 服务器会自动维护和使用索引.表数据的更新(如添加新行.更新行或删除行)会自动传播到所有相关的索引,这些对用户来说是完全透明的. 索引还可以提高实施主键和唯一键约束条件时的性能.如果没有索引,则每次对表执行DML 操作时都会扫描整个表(全表扫描). 4.2 类型 有多种类型的索引结构,可以根据需要使用

B树索引

B-Tree索引是最常见的索引结构,默认创建的索引就是B-Tree索引. 一.B树索引的结构 B-树索引是基于二叉树结构的.B-树索引结构有3个基本组成部分:根节点.分支节点和叶子节点.其中根节点位于索引结构的最顶端,而叶子节点位于索引结构的最底端,中间为分子节点.     叶子节点(Leaf node):包含条目直接指向表里的数据行.     分支节点(Branch node):包含的条目指向索引里其他的分支节点或者是叶子节点.     根节点(Branch node):一个B树索引只有一个根

oracle(sql)基础篇系列(五)——PLSQL、游标、存储过程、触发器

  PL/SQL PL/SQL 简介 每一种数据库都有这样的一种语言,PL/SQL 是在Oracle里面的一种编程语言,在Oracle内部使用的编程语言.我们知道SQL语言是没有分支和循环的,而PL语言是为了补充SQL语言的,是带有了分支和循环的语言. PL/SQL 语法 基本数据类型声明 declare v_name varchar2(20); v_temp number(1); v_count binary_integer := 0; v_sal number(7,2) := 4000.00

Oracle实践--PL/SQL基础之视图和索引

PL/SQL基础入门之视图和索引         PL/SQL:过程语言(Procedure  Language)和结构化语言(Structured Query Language)结合而成的编程语言,是对SQL的扩展,支持多种数据类型,如大对象和集合类型,可使用条件和循环等控制语句,可创建存储过程,程序包和触发器等,给sql语句的执行添加程序逻辑,与Oracle服务器和Oracle工具紧密集成,具有可移植性,灵活性和安全性. -----------------------------------

SQL Server调优系列基础篇(索引运算总结)

原文:SQL Server调优系列基础篇(索引运算总结) 前言 上几篇文章我们介绍了如何查看查询计划.常用运算符的介绍.并行运算的方式,有兴趣的可以点击查看. 本篇将分析在SQL Server中,如何利用先有索引项进行查询性能优化,通过了解这些索引项的应用方式可以指导我们如何建立索引.调整我们的查询语句,达到性能优化的目的. 闲言少叙,进入本篇的正题. 技术准备 基于SQL Server2008R2版本,利用微软的一个更简洁的案例库(Northwind)进行解析. 简介 所谓的索引应用就是在我们

[WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析

[WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析 标签: webkit内核JavaScriptCore 2015-03-26 23:26 2285人阅读 评论(1) 收藏 举报  分类: Webkit(34)  JavascriptCore/JIT(3)  版权声明:本文为博主原创文章,未经博主允许不得转载. 看到HorkeyChen写的文章<[WebKit] JavaScriptCore解析--基础篇(三)从脚本代码到JIT编译的代码实现>

[WebKit内核] JavaScriptCore深度解析--基础篇(一)字节码生成及语法树的构建

看到HorkeyChen写的文章<[WebKit] JavaScriptCore解析--基础篇(三)从脚本代码到JIT编译的代码实现>,写的很好,深受启发.想补充一些Horkey没有写到的细节比如字节码是如何生成的等等,为此成文. JSC对JavaScript的处理,其实与Webkit对CSS的处理许多地方是类似的,它这么几个部分: (1)词法分析->出来词语(Token): (2)语法分析->出来抽象语法树(AST:Abstract Syntax Tree): (3)遍历抽象语法

Oracle基础 索引

一.索引 索引是一种快速访问数据的途径,可提高数据库性能.索引使数据库程序无须对整个表进行扫描,就可以在其中找到所需的数据,就像书的目录,可以快速查找所需的信息,无须阅读整本书. (一)索引的分类 逻辑分类:单列索引.组合索引.唯一索引.非唯一索引,函数索引. 物理分类:区分索引.非分区索引.B树索引.正向索引.反向索引,位图索引. (二)索引的缺点: 1.索引占用表空间,创建太多索引可能会造成索引冗余. 2.索引会影响INSERT.UPDATE.DELETE语句的性能. (三)使用索引的原则:

Oracle 基础——索引

一.索引 索引是一种快速访问数据的途径,可提高数据库性能.索引使数据库程序无须对整个表进行扫描,就可以在其中找到所需的数据,就像书的目录,可以快速查找所需的信息,无须阅读整本书. 二.索引存在的问题 1.索引占用表空间,创建太多索引可能造成代码冗余 2.索引影响DML(INSERT.UPDATE.DELETE)语句的性能 三.使用索引的条件 1.一个字段包含大量的值 2.一个字段包含多个空值 3.多个字段经常出现在where 查询中 4.表非常大并且查询返回的数据量低于总数据的20% 四.索引的