- 浏览: 108812 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (75)
- JVM (22)
- 数据结构 (11)
- java 基础 (16)
- gc (6)
- jmock (1)
- Google (2)
- MapReduce (1)
- Memory (2)
- 算法 (2)
- cglib (1)
- jdk (3)
- 虚拟机 (3)
- 安全 (2)
- 多线程 (1)
- 工作 (1)
- 生活 (1)
- MongoDB (2)
- Hadoop (4)
- HDFS (2)
- cms (2)
- Spring (1)
- 网络协议 (1)
- GitHub (1)
- MYSQL 调优和使用必读(转) (1)
- 分布式 (2)
- Big Data (0)
- 技术Blog (1)
- Hbase (2)
- Zookeeper (1)
- paper (0)
最新评论
-
lzc_java:
Java线程安全兼谈DCL -
select*from爱:
it's nice
IT业薪水大揭秘
2. B 树索引的内部结构
我们可以使用如下方式将 B 树索引转储成树状结构的形式而呈现出来:
比如,对于上面的例子来说,我们把创建在 goodid 上的名为 idx_warecountd_goodid 的索引转储出来。
- SQL> select object_id from user_objects where object_name= 'IDX_WARECOUNTD_GOODID' ;
- OBJECT_ID
- ----------
- 7378
- SQL> alter session set events 'immediate trace name treedump level 7378' ;
打开转储出来的文件以后,我们可以看到类似下面的内容:
- ----- begin tree dump
- branch: 0x180eb0a 25225994 (0: nrow: 9, level : 2)
- branch: 0x180eca1 25226401 (-1: nrow: 405, level : 1)
- leaf: 0x180eb0b 25225995 (-1: nrow: 359 rrow: 359)
- leaf: 0x180eb0c 25225996 (0: nrow: 359 rrow: 359)
- leaf: 0x180eb0d 25225997 (1: nrow: 359 rrow: 359)
- leaf: 0x180eb0e 25225998 (2: nrow: 359 rrow: 359)
- …………………
- branch: 0x180ee38 25226808 (0: nrow: 406, level : 1)
- leaf: 0x180eca0 25226400 (-1: nrow: 359 rrow: 359)
- leaf: 0x180eca2 25226402 (0: nrow: 359 rrow: 359)
- leaf: 0x180eca3 25226403 (1: nrow: 359 rrow: 359)
- leaf: 0x180eca4 25226404 (2: nrow: 359 rrow: 359)
- …………………
其中,每一行的第一列表示节点类型: branch 表示分支节点(包括根节点),而 leaf 则表示叶子节点;第二列表示十六进制表示的节点的地址;第三列表示十进制表示的节点的地址;第四列表示相对于前一个节点的位置,根节点从 0 开始计算,其他分支节点和叶子节点从 -1 开始计算;第五列的 nrow 表示当前节点中所含有的索引条目的数量。比如我们可以看到根节点中含有的 nrow 为 9 ,表示根节点中含有 9 个索引条目,分别指向 9 个分支节点;第六列中的 level 表示分支节点的层级,对于叶子节点来说 level 都是 0 。第六列中的 rrow 表示有效的索引条目(因为索引条目如果被删除,不会立即被清除出索引块中。所以 nrow 减 rrow 的数量就表示已经被删除的索引条目数量)的数量,比如对于第一个 leaf 来说,其 rrow 为 359 ,也就是说该叶子节点中存放了 359 个可用索引条目,分别指向表 warecountd 的 359 条记录。
上面这种方式以树状形式转储整个索引。同时,我们可以转储一个索引节点来看看其中存放了些什么。转储的方式为:
我们从上面转储结果中的第二行知道,索引的根节点的地址为 25225994 ,因此我们先将其转换为文件号以及数据块号。
- SQL> select dbms_utility.data_block_address_file(25225994),
- 2 dbms_utility.data_block_address_block(25225994) from dual;
- DBMS_UTILITY.DATA_BLOCK_ADDRES DBMS_UTILITY.DATA_BLOCK_ADDRES
- ------------------------------ ------------------------------
- 6 60170
于是,我们转储根节点的内容。
打开转储出来的跟踪文件,我们可以看到如下的索引头部的内容:
- header address 85594180=0x51a1044
- kdxcolev 2
- KDXCOLEV Flags = - - -
- kdxcolok 0
- kdxcoopc 0x80: pcode=0: iot flags=--- is converted=Y
- kdxconco 2
- kdxcosdc 0
- kdxconro 8
- kdxcofbo 44=0x2c
- kdxcofeo 7918=0x1eee
- kdxcoavs 7874
- kdxbrlmc 25226401=0x180eca1
- kdxbrsno 0
- kdxbrbksz 8060
其中的 kdxcolev 表示索引层级号,这里由于我们转储的是根节点,所以其层级号为 2 。对叶子节点来说该值为 0 ; kdxcolok 表示该索引上是否正在发生修改块结构的事务; kdxcoopc 表示内部操作代码; kdxconco 表示索引条目中列的数量; kdxcosdc 表示索引结构发生变化的数量,当你修改表里的某个索引键值时,该值增加; kdxconro 表示当前索引节点中索引条目的数量,但是注意,不包括 kdxbrlmc 指针; kdxcofbo 表示当前索引节点中可用空间的起始点相对当前块的位移量; kdxcofeo 表示当前索引节点中可用空间的最尾端的相对当前块的位移量; kdxcoavs 表示当前索引块中的可用空间总量,也就是用 kdxcofeo 减去 kdxcofbo 得到的。 kdxbrlmc 表示分支节点的地址,该分支节点存放了索引键值小于 row#0 (在转储文档后半部分显示)所含有的最小值的所有节点信息; kdxbrsno 表示最后一个被修改的索引条目号,这里看到是 0 ,表示该索引是新建的索引; kdxbrbksz 表示可用数据块的空间大小。实际从这里已经可以看到,即便是 PCTFREE 设置为 0 ,也不能用足 8192 字节。
再往下可以看到如下的内容。这部分内容就是在根节点中所记录的索引条目,总共是 8 个条目。再加上
- row#0[8043] dba: 25226808=0x180ee38
- col 0; len 8; (8): 31 30 30 30 30 33 39 32
- col 1; len 3; (3): 01 40 1a
- ……
- row#7[7918] dba: 25229599=0x180f91f
- col 0; len 8; (8): 31 30 30 31 31 32 30 33
- col 1; len 4; (4): 01 40 8f a5
kdxbrlmc 所指向的第一个分支节点,我们知道该根节点中总共存放了 9 个分支节点的索引条目,而这正是我们在前面所指出的为了管理 3611 个叶子节点,我们需要 9 个分支节点。
每个索引条目都指向一个分支节点。其中 col 1 表示所链接的分支节点的地址,该值经过一定的转换以后实际就是 row# 所在行的 dba 的值。如果根节点下没有其他的分支节点,则 col 1 为 TERM ; col 0 表示该分支节点所链接的最小键值。其转换方式非常复杂,比如对于 row #0 来说, col 0 为 31 30 30 30 30 30 30 33 ,则将其中每对值都使用函数 to_number(NN,’XX’) 的方式从十六进制转换为十进制,于是我们得到转换后的值: 49,48,48,48,48,48,48,51 ,因为我们已经知道索引键值是 char 类型的,所以对每个值都运用 chr 函数就可以得到被索引键值为: 10000003 。实际上,对 10000003 运用 dump 函数得到的结果就是: 49,48,48,48,48,48,48,51 。所以我们也就知道, 10000003 就是 dba 为 25226808 的索引块所链接的最小键值。
- SQL> select dump( '10000003' ) from dual;
- DUMP('10000003' )
- -------------------------------------
- Typ=96 Len=8: 49,48,48,48,48,48,48,50
接下来,我们从根节点中随便找一个分支节点,假设就是 row#0 所描述的 25226808 。对其运用前面所介绍过的 dbms_utility 里的存储过程获得其文件号和数据块号,并对该数据块进行转储,其内容如下所示。可以
- row#0[8043] dba: 25226402=0x180eca2
- col 0; len 8; (8): 31 30 30 30 30 33 39 33
- col 1; len 3; (3): 01 40 2e
- ………
- row#404[853] dba: 25226806=0x180ee36
- col 0; len 8; (8): 31 30 30 30 31 36 34 30
- col 1; len 3; (3): 01 40 09
- ----- end of branch block dump -----
发现内容与根节点完全类似,只不过该索引块中所包含的索引条目(指向叶子节点)的数量更多了,为 405 个。这也与我们前面所说的 一个分支索引块可以存放大约 405 ( 6488/16 )个索引条目完全一致。
然后,我们从中随便挑一个叶子节点,对其进行转储。假设就选 row#0 行所指向的叶子节点,根据 dba 的值: 25226402 可以知道,文件号为 6 ,数据块号为 60578 。将其转储以后,其内容如下所示,我只显示与分支节点不同的部分。
- ………
- kdxlespl 0
- kdxlende 0
- kdxlenxt 25226403=0x180eca3
- kdxleprv 25226400=0x180eca0
- kdxledsz 0
- kdxlebksz 8036
其中的 kdxlespl 表示当叶子节点被拆分时未提交的事务数量; kdxlende 表示被删除的索引条目的数量; kdxlenxt 表示当前叶子节点的下一个叶子节点的地址; kdxlprv 表示当前叶子节点的上一个叶子节点的地址; kdxledsz 表示可用空间,目前是 0 。
转储文件中接下来的部分就是索引条目部分,每个条目包含一个 ROWID ,指向一个表里的数据行。如下所示。其中 flag 表示标记,比如删除标记等;而 lock 表示锁定信息。 col 0 表示索引键值,其算法与我们在前面介绍分支节点时所说的算法一致。 col 1 表示 ROWID 。我们同样可以看到,该叶子节点中包含了 359 个索引条目,与我们前面所估计的一个叶子节点中大约可以放 360 个索引条目也是基本一致的。
- row#0[8018] flag: -----, lock: 0
- col 0; len 8; (8): 31 30 30 30 30 33 39 33
- col 1; len 6; (6): 01 40 2e 93 00 16
- row#1[8000] flag: -----, lock: 0
- col 0; len 8; (8): 31 30 30 30 30 33 39 33
- col 1; len 6; (6): 01 40 2e e7 00 0e
- …………
- row#358[1574] flag: -----, lock: 0
- col 0; len 8; (8): 31 30 30 30 30 33 39 37
- col 1; len 6; (6): 01 40 18 ba 00 1f
-
----- end of leaf block dump -----
发表评论
-
哈希表
2013-05-03 11:03 1629转载自 ---- http://blog.java ... -
Java 链表
2013-01-18 15:27 970转载自 ---- http://359094247.iteye ... -
哈夫曼与压缩
2013-01-18 15:24 907转载自 ---- http://359094247.iteye ... -
排序算法java版(转载)
2011-08-10 14:06 899转载自 ---- http://yiyickf.iteye.c ... -
(转)B树、B-树、B+树、B*树都是什么
2011-08-03 16:55 704B 树 即二叉搜 ... -
(转)深入研究B树索引(五)续
2011-08-03 16:53 8745.3 重建 B 树索引对于查询性能的影响 ... -
(转)深入研究B树索引(五)
2011-08-03 16:53 9175. 重建 ... -
(转)深入研究B树索引(四)续
2011-08-03 16:52 8014.2 B 树索引的 ... -
(转)深入研究B树索引(三、四)
2011-08-03 16:51 7813. B 树索引的访问 ... -
(转)深入研究B树索引(一)
2011-08-03 16:50 1074摘要: 本文对B 树索引的结构、内部管理等方面做了一个 ...
相关推荐
**深入研究B树索引** B树(B-tree)是一种自平衡的树数据结构,广泛应用于数据库和文件系统中,特别是在实现索引存储时。它能够保持数据有序,允许快速查找、插入和删除操作。本篇文章将深入探讨B树的核心概念、...
B树索引是一种高效的数据检索方法,广泛应用于数据库系统中,特别是关系型数据库管理系统。B树索引的主要目的是加速数据的查找、排序和更新操作,通过构建一种平衡的多路搜索树结构,使得数据访问更加高效。 B树...
总的来说,B树索引和自创Connect都是为了提升数据检索的效率。理解它们的原理和特点,有助于我们设计更高效的数据库系统,并在实际项目中选择最适合的数据结构。通过源码分享,我们可以深入研究这些数据结构的实现,...
3. B+树索引结构:B+树是一种广泛使用的树形结构数据索引方式,是B树的一种变种,特别适合用于磁盘存储。它能够有效地组织大量数据,并支持快速的查找、顺序访问、插入和删除操作。在数据库系统中,B+树被广泛用作...
B*树(B-star tree)是B树的一个变种,它在B树的基础上进行了优化,以适应大规模数据存储和高效查询的需求。 B*树索引的核心特点在于它的分层结构,每个节点可以包含多个子节点,并且每个节点可以存储多个键值和...
磁盘数据页存储结构是数据库管理中的一项关键...在深入研究索引和查询原理之前,理解数据页的存储结构是必不可少的。只有这样,我们才能更好地掌握数据库系统的内部工作机制,进而设计出更优的索引和执行更高效的查询。
cpp-DeepDataBase是一个使用B树索引实现的关系数据库引擎,它的设计目标是提供一个轻量级、高效的数据库解决方案。DeepDataBase是用C++编程语言编写的,这意味着它利用了面向对象的特性,同时保持了较低级别的性能...
在IT领域,数据结构是计算机科学中的核心概念之一,它为高效地存储和处理数据提供了理论基础。...对这些文件进行深入研究,不仅可以了解B+树索引的实现,还可以进一步提升C语言编程和数据结构理解的能力。
R树是由Guttman在1984年提出的一种多维索引结构,它是对B树的扩展,用于存储和查询具有空间属性的数据。R树的主要目标是在多维空间中有效地组织和检索数据,通过构建一种平衡的树形结构来降低搜索成本。 在R树中,...
通过对这些文件的研究,我们可以深入理解C语言和B树在实际问题中的应用,提升编程和数据结构设计的能力。 总的来说,C语言数据结构中的B树在图书管理系统中的应用,既展示了数据结构理论的实际价值,也锻炼了编程和...
B-树实际上是B树的一个变种,通常在数据库索引中较少提及,更多是在学术研究领域讨论。 **特点:** - 具有相同的关键字数量,但比B树少一个子节点; - 在每个节点中,关键字的数量等于子节点的数量减一; - 每个...
为了更好地理解这些数据结构,可以先从B-树入手,熟悉其基本原理和操作流程,然后再研究B+树的差异。项目提供的源代码可以作为实践平台,通过阅读和调试代码,加深对B-树和B+树的理解。 总结来说,这个C++实现的B-...
文章通过对B+树数据库索引结构的分析,研究了其关系表,并评估了B+树的索引效果。在此基础上,设计了电力大数据混合索引的结构,并对其性能进行了深入分析。 在索引设计过程中,电力大数据的特征和规律被充分考虑,...
通过深入研究和应用如QR2树索引等创新方法,可以显著提升空间数据库的性能,满足日益增长的大数据处理需求。随着技术的不断进步,未来空间数据库索引技术将继续发展,为地理信息科学、城市规划、自然资源管理等领域...
在关系数据库管理系统中,B+树索引是提高查询性能的关键技术。索引的构建和维护是数据库管理的重要组成部分,它需要在保证数据一致性的同时,提供高效的查询和更新操作。通过Java实现B+树算法,不仅可以优化数据库...
总结,这个压缩包提供了一个学习和研究B+树的良好平台,对于理解数据结构和算法,以及提高C语言编程技能都非常有价值。通过分析和实践其中的代码,你可以掌握B+树的基本操作,并了解到如何在实际项目中优化数据访问...
**B树(B-tree)**是一种自平衡的查找树数据结构,它能够保持数据排序,适合用于数据库和文件系统等领域。...对于给定的压缩文件“bplustree”,可能包含了B树或B+树的示例代码和相关工具,供学习者深入研究和实践。