mysql索引为啥要选择B+树 (下)

有读者在 mysql索引为啥要选择B+树 (上) 上篇文章中留言总结了选择 B+ 树的原因,大体上说对了,今天我们再一起来看看具体的原因。

  • 索引为什么要保存在硬盘中

首先要明白几个概念,服务器存储一般分内存和硬盘,内存的大小相对于硬盘来说是很小的。内存的访问速度是纳秒级别的,非常快,而硬盘的访问速度相对内存来说就比较慢了。

不管是访问内存还是硬盘数据,操作系统都是按数据页来读取数据的,即每访问一次硬盘或内存,只读取一页大小的数据,一页的大小约等于 4 kb,向硬盘读取数据的操作叫做磁盘 IO。

看到这里你或许会知道了 mysql 索引为啥不保存在内存中了吧,一方面是虽然内存访问速度快但容量一般都比较小,存不了多少数据,再一个 mysql 需要让数据持久化,如果服务器断电或异常重启会导致数据丢失。

  • 怎么让二叉搜索树支持区间查询

上篇文章中提到过二叉搜索树,为了让二叉搜索树也支持区间查询,我们把二叉树的叶子节点通过一个双向链表来连接,并且这个链表是有序的,注意叶子节点和普通节点是不一样的,注意看下面的图。

因此只需要先找到区间的起始值在链表中的位置,然后再往后遍历,直到遍历到区间的终止值,即可完成区间查询。如下图查找 7-30 这个区间的数据。

  • 如何提升查询速度

因为二叉搜索树保存在硬盘中,我们每访问一个节点,就对应着一次硬盘 IO 操作,上面有说过向硬盘读取数据速度比较慢。因此树的高度就代表硬盘 IO 操作的次数,所以我们要想办法让树的高度变矮,来减少硬盘 IO。

要想树变矮一些,那就把树多分一些叉来吧,变成一颗多叉树。下面分别用二叉树和五叉树来存储 16 条数据,看下树的高度又怎样的变化。

根节点一般存储在内存中,普通节点和叶子结点保存在硬盘中,因此显然二叉树的高度为 5,需要 5 次硬盘 IO,而五叉树的高度为 2,查询一个数据只需要 2 次硬盘 IO。

当然这仅仅是一个小数据的例子,如果有一亿条数据,我们构建一个 100 叉树,这棵树的高度也只有 3,因此多叉树能大大降低硬盘 IO,提升查询速度。

那么问题又来了,对于相同的数据量,是不是构建的多叉树的叉越多越好呢,因为叉越多树的高度就会越矮。

上面有说过操作系是按数据页大小来访问硬盘的,每次 IO 只读取一个数据页大小的数据,如果要读取的数据大于一个数据页,则会导致多次 IO。因此我们要尽量让每个节点的数据大小刚好等于一个数据页大小,即每访问一个节点只需一次 IO。

  • 插入和删除数据怎么办

上面讲的其实都是为了提高查询性能的,mysql 通常还有插入和删除操作的,这里我们再简单说一下 B+ 树如何处理插入和删除节点的操作。

这里我们把多叉树称作 m 叉树,这个 m 值是通过数据页大小和节点数计算出来的,尽量保证每访问一个节点就是一个数据页的大小,而且每个节点最多只有 m 个子节点。

现在我们要往数据库中插入新的数据,即要往 m 叉树中插入新的节点,这可能就会导致某些节点的子节点个数大于 m,也就会导致该节点大小大于一个数据页,访问该节点就需要多次 IO。

为了解决这个问题,m 叉树会把该节点分裂成两个节点,然后改分裂操作又会导致其父节点的子节点数可能超过 m,我们再用同样的方法分裂节点,一直影响到根节点。

删除操作也是类似的思想,如果有频繁的删除节点,就会导致某些节点的子节点过少,就会浪费存储空间并降低查询效率。所以就要想办法让这些节点合并起来,合并的话就有可能会导致其子节点数超过 m,超过的话就再用上面的分裂方法分裂子节点。

关于节点分裂和合并操作就简单说这些了,也不画图了,知道这个处理思想就好了。

下面再总结一下 B+ 树:

B+ 树就是一种多叉树,是由二叉搜索树不断演变过来的,为了满足区间快速查询,B+ 树的叶子节点通过双向链表串联起来。

这里使用双向链表是为了支持顺序和倒序查询,虽然双向链表相对于单向链表虽然会浪费一倍的指针空间,但是在硬盘中这点空间几乎微乎其微,用这点空间换时间是一件很值得的事情。

B+ 树的子节点数不超过 m 个,同时也不能少于 m/2 个,一旦超过就需要分裂,一旦少于就需要合并。

关于 mysql InnoDB 引擎为啥要选择 B+ 树就写到这了,文中图片来源于极客时间《数据结构与算法之美》专栏。对文章如有疑问,欢迎留言交流,如文章有描述不当之处,也希望大家批评指出。如文章对你有帮助,点个赞再走哈,感谢支持。

转载于:https://juejin.im/post/5c8dce95f265da2da7721946

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/536650.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

des加解密java c#,C#编写DES加密、解密类

这个C#类封装的DES加密解密,可以使用默认秘钥进行加密、解密,也可以自定义秘钥进行加密、解密,调用简单方便。示例一:using System;using System.Security.Cryptography;using System.Text;namespace DotNet.Utilities{/// /// DE…

八年开发程序员浅析SpringBoot 之 Shiro 与 Redis 多级缓存问题

前言 来自不愿意透露姓名的小师弟的投稿。这篇主要讲了,项目中配置了多缓存遇到的坑,以及解决办法。 发现问题 在一次项目实践中有实现多级缓存其中有已经包括了 Shiro 的 Cache ,本以为开启 redis 的缓存是一件很简单的事情只需要在启动类上…

Web端H.265播放器研发解密

音视频编解码对于前端工程师是一个比较少涉足的领域,涉及到流媒体技术中的文本、图形、图像、音频和视频多种理论知识的学习,才能够应用到具体实践中,本团队在多媒体领域深耕两年多,才算是有一定产出,我们自研web播放器…

拳击 武术java父类,拳击是一种很有力量的武术类型

原标题:拳击是一种很有力量的武术类型拳击是一种很有力量的武术类型,拳击比赛策略有很多,围绳技术是其中之一。那么拳击比赛策略技巧有哪些呢?下面养生之道网为您解析拳击比赛策略技巧有哪些,看看吧。1、当拳手靠在围绳…

捧上天的AI落地困难,“ 不懂变通”的华为云如何应付?

前几年,AI几乎被捧上天,各大公司倾巢出动,推出了不少吸眼球的应用和产品。如今,这些AI成果是否真得让企业从中获得价值?绕不开的数据、隐私和安全问题作何解?不同领域、不同规模、不同技术能力的企业如何最…

Apache-Flink深度解析-DataStream-Connectors之Kafka

Kafka 简介Apache Kafka是一个分布式发布-订阅消息传递系统。 它最初由LinkedIn公司开发,LinkedIn于2010年贡献给了Apache基金会并成为顶级开源项目。Kafka用于构建实时数据管道和流式应用程序。它具有水平扩展性、容错性、极快的速度,目前也得到了广泛的…

Java使用继承的语法是,Java基础语法八 继承

1、超类和子类超类和子类父类与子类多态:一个对象变量可以指示多种实际类型的现象称为多态一个变量可以引用父类对象,也可以引用其子类对象,这就是多态。不能将一个超类的引用赋给子类变量,因为调用子类方法时可能发生运行错误子类…

kaka 1.0.0 重磅发布,服务于后端的事件领域模型框架。

百度智能云 云生态狂欢季 热门云产品1折起>>> kaka 1.0.0正式发布了,从三个月前的kaka-notice-lib 1.0.0的发布,经过多次研磨,终于迎来了本次重大更新。 kaka是一款服务于java后端的事件领域模型框架,主要目的为解耦业…

java配置文件工具类,java项目加载配置文件的工具类

java项目加载配置文件的工具类package com.loadproperties;import java.io.IOException;import java.io.InputStream;import java.util.Properties;public class ConfigUtil {private static InputStream input;private volatile Properties configuration new Properties();/…

如何把WAV格式音频转换为MP3格式

WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频信息资源,被Windows平台及其应用程序所广泛支持,因此在声音文件质量和CD相差无几&…

php 异步处理类,php异步处理类

该类可以请求HTTP和HTTPS协议,还可以处理301、302重定向以及GZIP压缩等。[PHP]代码//使用方法require(asynHandle.class.php);$obj new asynHandle();$result $obj->Request(http://baidu.com);$result2 $obj->Get(https://mail.google.com/);echo "{…

恶意软件盯上了加密货币,两家以色列公司受到攻击

近日,网络安全公司Palo Alto Networks威胁研究部门Unit 42发博称,已确认Cardinal RAT自2017年4月起对两家从事外汇和加密交易软件开发的以色列金融科技公司发起过攻击。 Cardinal RAT是可远程访问特洛伊木马(RAT),攻击…

php 自定义打印模板下载,PHP – 创建自定义模板系统?

我已经在这里搜索过,令人惊讶的是我找不到答案.我发现了一个类似的线程,但没有真正的解决方案.复杂的部分是循环,如果我不需要循环我可以只是做一个常规替换.所以,我有一个带有一些标记的.html文件,如下所示:{{startloop}}{{imgname}}{{endLoop}}我想要做的是用其他…

腾讯财报中“最大秘密”:2018云收入91亿元,交首份TO B答卷

腾讯财报中“最大秘密”云业务收入又一次被公开了:2018年,腾讯云收入91亿元,增长100%。 3月21日,腾讯发布2018年Q4及全年财报,2018全年收入3126.94亿元同比增长32%,净利润(Non-GAAP)774.69亿元。而被列进“…

根据坐标如何在matlab中l连成曲线,matlab中,如何将两条曲线画在一个坐标系里,plot(x1,x2,y1,y2)还是怎样...

matlab中,如何将两条曲线画在一个坐标系里,plot(x1,x2,y1,y2)还是怎样以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!matlab中,如何将两条曲线画在一个坐…

Android 物联网 传感器

前几天做了一个嵌入式课设。将传感器收集到的数据传到手机制作的APP里。 项目中涉及到的主要的java代码和xml布局文件上传到了github,https://github.com/123JACK123jack/Android转载于:https://www.cnblogs.com/libin123/p/10578601.html

java已被弱化签名,高效Java第四十条建议:谨慎设计方法签名

作用有助于设计易于学习和使用的API。如何做——谨慎地选择方法的名称1.选择易于理解的,并且与同一个包中的其他名称风格一致的名称。2.选择与大众认可的名称相一致的名称。如何做——不要过于追求提供便利的方法每个方法都应该尽其所能。方法太多会使类难以学习、使…

curl有php内存缓存,PHP CURL内存泄露的解决方法

PHP CURL内存泄露的解决方法curl配置平淡无奇,长时间运行发现一个严重问题,内存泄露!不论用单线程和多线程都无法避免!是curl访问https站点的时候有bug!内存泄露可以通过linux的top命令发现,使用php函数mem…

MySQL学习【第五篇SQL语句上】

一.mysql命令 1.连接服务端命令 1.mysql -uroot -p123 -h127.0.0.1 2.mysql -uroot -p123 -S /tmp/mysql.sock 3.mysql -uroot -p123 -hlocalhost 4.mysql -uroot -p123 2.mysql登陆后的一些命令 1.\h或者help   查看帮助 2.\G       格式化查看数据(以k…

phpexcel.php linux,phpexcel在linux系统报错如何解决

最近有个tp3.2的项目迁移到linux系统上了,突然有天发现原本在win server 2008上运行没问题的excel导出功能在新的系统上不能使用了。报错如下:说是1762行有问题,找到这个文件的代码看看:/*** Get an instance of this class** acc…