转:为什么数据库选B-tree或B+tree而不是二叉树作为索引结构
转载至:https://blog.csdn.net/sinat_27602945/article/details/80118362
B-Tree就是我们常说的B树,一定不要读成B减树,否则就很丢人了。B树这种数据结构常常用于实现数据库索引,因为它的查找效率比较高。
磁盘IO与预读
磁盘读取依靠的是机械运动,分为寻道时间、旋转延迟、传输时间三个部分,这三个部分耗时相加就是一次磁盘IO的时间,大概9ms左右。这个成本是访问内存的十万倍左右;正是由于磁盘IO是非常昂贵的操作,所以计算机操作系统对此做了优化:预读;每一次IO时,不仅仅把当前磁盘地址的数据加载到内存,同时也把相邻数据也加载到内存缓冲区中。因为局部预读原理说明:当访问一个地址数据的时候,与其相邻的数据很快也会被访问到。每次磁盘IO读取的数据我们称之为一页(page)。一页的大小与操作系统有关,一般为4k或者8k。这也就意味着读取一页内数据的时候,实际上发生了一次磁盘IO。
B-Tree与二叉查找树的对比
我们知道二叉查找树查询的时间复杂度是O(logN),查找速度最快和比较次数最少,既然性能已经如此优秀,但为什么实现索引是使用B-Tree而不是二叉查找树,关键因素是磁盘IO的次数。
数据库索引是存储在磁盘上,当表中的数据量比较大时,索引的大小也跟着增长,达到几个G甚至更多。当我们利用索引进行查询的时候,不可能把索引全部加载到内存中,只能逐一加载每个磁盘页,这里的磁盘页就对应索引树的节点。
一、 二叉树
我们先来看二叉树查找时磁盘IO的次:定义一个树高为4的二叉树,查找值为10:

第一次磁盘IO:

第二次磁盘IO

第三次磁盘IO

第四次磁盘IO:

从二叉树的查找过程了来看,树的高度和磁盘IO的次数都是4,所以最坏的情况下磁盘IO的次数由树的高度来决定。
从前面分析情况来看,减少磁盘IO的次数就必须要压缩树的高度,让瘦高的树尽量变成矮胖的树,所以B-Tree就在这样伟大的时代背景下诞生了。
二、B-Tree
m阶B-Tree满足以下条件:
1、每个节点最多拥有m个子树
2、根节点至少有2个子树
3、分支节点至少拥有m/2颗子树(除根节点和叶子节点外都是分支节点)
4、所有叶子节点都在同一层、每个节点最多可以有m-1个key,并且以升序排列
如下有一个3阶的B树,观察查找元素21的过程:

第一次磁盘IO:

第二次磁盘IO:

这里有一次内存对比:分别跟3与12对比
第三次磁盘IO:

这里有一次内存比对,分别跟14与21比对
从查找过程中发现,B树的比对次数和磁盘IO的次数与二叉树相差不了多少,所以这样看来并没有什么优势。
但是仔细一看会发现,比对是在内存中完成中,不涉及到磁盘IO,耗时可以忽略不计。另外B树种一个节点中可以存放很多的key(个数由树阶决定)。
相同数量的key在B树中生成的节点要远远少于二叉树中的节点,相差的节点数量就等同于磁盘IO的次数。这样到达一定数量后,性能的差异就显现出来了。
转:为什么数据库选B-tree或B+tree而不是二叉树作为索引结构的更多相关文章
- Mysql Index、B Tree、B+ Tree、SQL Optimization
catalog . 引言 . Mysql索引 . Mysql B/B+ Tree . Mysql SQL Optimization . MySQL Query Execution Process 1. ...
- 数据库索引<一> 索引结构表结构
有很长时间没有更新博客了,再过几天都2月分了,如果再不更新一篇,我1月分都没有更新,保持连续,今天更新一篇. 最近没有什么看技术方面的东西,游戏,画画搞这些去了.我发现我每年一到年底就是搞这些东西,其 ...
- 数据库为什么要用B+树结构--MySQL索引结构的实现(转)
B+树在数据库中的应用 { 为什么使用B+树?言简意赅,就是因为: 1.文件很大,不可能全部存储在内存中,故要存储到磁盘上 2.索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数(为什么使用B-/ ...
- 关系型数据库为什么喜欢使用B+树作为索引结构? (转)
问题1. 数据库为什么要设计索引? 图书馆存了1000W本图书,要从中找到<架构师之路>,一本本查,要查到什么时候去? 于是,图书管理员设计了一套规则: (1)一楼放历史类,二楼放文学类, ...
- 【Java面试】Mysql为什么使用B+Tree作为索引结构
一个工作8年的粉丝私信了我一个问题. 他说这个问题是去阿里面试的时候被问到的,自己查了很多资料也没搞明白,希望我帮他解答. 问题是: "Mysql为什么使用B+Tree作为索引结构" ...
- B-Tree、B+Tree和B*Tree
B-Tree(这儿可不是减号,就是常规意义的BTree) 是一种多路搜索树: 1.定义任意非叶子结点最多只有M个儿子:且M>2: 2.根结点的儿子数为[2, M]: 3.除根结点以外的非叶子结点 ...
- 【Luogu1501】Tree(Link-Cut Tree)
[Luogu1501]Tree(Link-Cut Tree) 题面 洛谷 题解 \(LCT\)版子题 看到了顺手敲一下而已 注意一下,别乘爆了 #include<iostream> #in ...
- 【BZOJ3282】Tree (Link-Cut Tree)
[BZOJ3282]Tree (Link-Cut Tree) 题面 BZOJ权限题呀,良心luogu上有 题解 Link-Cut Tree班子提 最近因为NOIP考炸了 学科也炸了 时间显然没有 以后 ...
- [LeetCode] Encode N-ary Tree to Binary Tree 将N叉树编码为二叉树
Design an algorithm to encode an N-ary tree into a binary tree and decode the binary tree to get the ...
随机推荐
- 年底获奖人太多?奖状可以用Smartbi电子表格这么做!
又到一年年终时,你的年终奖到手了吗?奖金没领到,发个奖状压压惊 今天给大家分享年终奖相关的年终奖状的批量套打功能,保证你的奖状及时到手! 示例说明 现有多个人员的奖励需要通知,需要生成可翻页的奖状.并 ...
- Spring系列22:Spring AOP 概念与快速入门篇
本文内容 Spring AOP含义和目标 AOP相关概念 声明式AOP快速入门 编程式创建代理对象 Spring AOP含义和目标 OOP: Object-oriented Programming 面 ...
- Docker容器里部署Apache+PHP+MariaDB+phpMyAdmin
前面讲到了创建MariaDB,这次在前面的基础上搭建phpMyAdmin服务,以便友好的管理数据库MariaDB.MariaDB的docker独立出来,这样方便管理,易于扩展.这次我们基于Docker ...
- linux系统挂载磁盘
linux系统挂载磁盘 ## 将硬盘挂载到/mnt/disk1下 # 检查磁盘状态,确认分区 fdisk -l # 格式化磁盘(分区) mkfs.ext4 /dev/sda #根据机器上的命名 以sd ...
- Windows命令(ping、telnet、netstat详解)
转至:https://www.cnblogs.com/lisuyun/articles/5864744.html netstat详解转自http://wsmajunfeng.iteye.com/blo ...
- PyTorch深度学习实践——反向传播
反向传播 课程来源:PyTorch深度学习实践--河北工业大学 <PyTorch深度学习实践>完结合集_哔哩哔哩_bilibili 目录 反向传播 笔记 作业 笔记 在之前课程中介绍的线性 ...
- appium ios 相对坐标点击和控件滑动操作
环境: 系统:ios 10.13.6 (17G12034) appium:1.14.0 xcode:10.1 iphone:iphone7 12.4 在尝试使用driver.tap([(a,b)],5 ...
- egg中使用sequelize事务,实现原子性
let transaction; try { // 建立事务对象 transaction = await this.ctx.model.transaction(); const house = awa ...
- java面试:java基础、Io、容器
1.java基础 1.JDK 和JRE有什么区别 JDK:java开发工具包,java开发运行环境.包含了JRE. JRE:java运行环境,包含java虚拟机,java基础类库. 2.jav ...
- 如何取消 UIView 动画?
原文链接 最近项目中有一个需求是需要手动点击相机对焦,这里由于相机对焦部分需要一个类似于系统对焦框一样的缩放动画,同时动画时长为0.3秒,因此这里就有一个很普遍的需求,如果用户在0.3秒内继续点击对焦 ...