MySQL采用B+树作为索引的原因

2023-11-10

MySQL采用B+树作为索引的原因

1、MySQL的索引结构是如何查询的

在MySQL中,存储的数据记录都是持久化到磁盘中的,数据包含索引和记录,当MySQL查询数据时,由于索引也是持久化在磁盘上面的,首先会从磁盘上读取索引到缓存中,然后再通过索引从磁盘上面检索数据读取待内存中,在这期间会进去内存与磁盘之间的IO交互,而磁盘IO次数越多的话,所消耗的时间就会从多,所以当从磁盘检索的IO次数越少时,查询速率就会越快,而MySQL是可以范围查询的,所以MySQL索引的数据结构选取就会减少IO次数,并能支持范围查找

2、二叉查找树

二叉查找树是一种经典的数据结构,在二叉查找树中,左子树的键值总是小于根的键值,右子树的键值总是大于根的键值,因此可以通过中序遍历来查询键值的顺序输出,二叉树节点中存储了键(key)和数据(data),如下图所示,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6yuDnKHU-1655435000382)(https://gitee.com/ycodingnow/blogimage/raw/master/image/20220617094702.png)]

对于上图的二叉查找树,当我们需要查找键值为5的记录时,先通过根进行比较,其键值是6,6大于5,接着查询6的左子树,而找到3,5大于3,再找到其右子树,一共进行了3次查找,若如果构造的二叉查找树逐渐退化为链表结构的话, 查询的效率就趋向于链表查询了,故而引出了平衡二叉树,又称之为AVL树

3、平衡二叉树

平衡二叉树定义如下,首先符合二叉查找树的概念,其次必须满足任何节点的两个子树的高度差最大差为1

平衡二叉树保证了树的构造是平衡的,当我们插入或删除数据导致不满足平衡二叉树不平衡时,平衡二叉树会进行调整树上的节点来保持平衡

平衡二叉树相比于二叉查找树来说,查找效率更稳定,总体的查找速度也更快

4、B树

我们知道,在数据库存储时,数据和索引都会存储在磁盘这种外围设备中去,但是和内存相比,磁盘读取的效率会很低下,所以需要尽量避免磁盘IO操作

在进行磁盘读取时,读取数据都是按照磁盘块来进行读取的,并不是一条一条地从数据库进行读取的,而在磁盘中,磁盘读取数据的最小单位为扇区,一个扇区的大小为512B,而操作系统最小读取的块大小为4KB,所以一次磁盘IO会从一次性地读取8个扇区

在二叉查找树和平衡二叉树中,每个节点存储的数据都只是一个键值和对应的数据的,那么实际读取的磁盘块就只会存储一个节点信息,当我们需要读取的数据量非常大时,那么树的高度就会非常高,就会进行多次磁盘IO操作,查询效率就会非常低下

而B树(BaLance Tree),即为平衡树的意思,在B树中,每个节点被称之为页,在MySQL中数据读取的基本单位都是页,B树相对于平衡二叉树,每个节点存储了更多的键值(key)和数据(data),并且每个节点拥有更多的子节点,子节点的个数一般称为阶,高度也会很低

基于这个特性,B树查找数据读取磁盘的次数将会很少,数据的查找效率也会比平衡二叉树高很多

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zyyLivfy-1655435000383)(https://gitee.com/ycodingnow/blogimage/raw/master/image/20220617105855.png)]

5、B+树

B+树和二叉树、平衡二叉树一样,都是经典的数据结构,B+树是由B树和索引顺序访问方法演化而来的,B+树是基于B树的进一步优化而来,与B树相比

  • B+树的非叶子节点是不存储键值,只是存储键值(key),而B树节点不仅存储键值(key)还会存储数据(data),MySQL在使用InnoDB引擎的时候页大小默认是16KB,当页中不存储数据时,存储的键值就会更多,相应的树就会显得’更矮更胖’,这样在进行数据查询时,磁盘IO的次数就会越少
  • B+树的索引数据都是存放在叶子节点的,并且叶子节点是双向链表有序排列的,那么B+树进行范围查找,顺序查找的效率就会更快,而在非叶子节点中,各个页之间都是双向链表进行连接的,

B+树是为磁盘或其他直接存取辅助设备设计的一种平衡查找树,在B+树中,所有记录节点都是按照键值的大小顺序存放在同一层的叶子节点上的,由各叶子节点指针进行连接,先来看一个B+树,其高度为2,每页可以存放4条记录,扇出(fan out)为5,如下图所示

从图中可以看出,所有记录都是存放在叶子节点上的,并且是顺序存放的,如果用户从最左边的叶子节点开始顺序遍历,可以得到所有键值的顺序排序:

5,10,15,20,25,30,50,55,60,65,75,80,85,90

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1PutriAv-1655435000384)(https://gitee.com/ycodingnow/blogimage/raw/master/image/20220617105002.png)]

在数据库中,B+树的高度一般都是在24层,这就是说查找某一键值的行记录时最多只需要2到4次IO,因为当前一般的机器磁盘每秒可以做100次IO,24次的IO意味着查询时间只需要0.02~0.04秒

数据库中的B+树索引可以分为聚集索引(clustered index)和辅助索引(secondary index),但是不管是聚集还是辅助索引,其内部都是B+树的,即高度平衡的

6、聚集索引与辅助索引
  • 聚集索引: 以InnoDB作为存储引擎的表,表中的数据都会有一个主键,InnoDB是把数据存放在B+树的,同时叶子节点存放的即为整张表的行记录数据,也将聚集索引的叶子节点称为数据页,同B+树数据结构一样,每个数据页都通过一个双向链表来进行链接,由于实际的数据页只能按照一棵B+树来进行排序,因此每张表中只能有一个聚集索引,在多数情况下,查询优化器倾向于采用聚集索引,因为聚集索引能够在B+树索引的叶子节点直接找到数据,此外,由于定义了数据的逻辑顺序,聚集索引能够特别快地访问指定范围内的查询,查询优化器能够快速发现某一段范围的数据页需要扫描
  • 非聚集索引:以主键以外的列值作为键值构建的B+树索引,我们称之为非聚集索引,与聚集索引相比,非聚集索引的叶子节点不存储表中的数据,而是存储该列对应的主键,想要查找数据我们还需要根据主键再去聚集索引中进行查找,这个再根据聚集索引查找数据的过程,这种操作称为回表

聚集索引叶子节点存放在所有数据,聚集索引与辅助索引不同的是,叶子节点存放的是否是一整行的信息

在InnoDB中,聚集索引中叶子节点存放的是数据行的所有信息,而在非聚集索引中,叶子节点存放的是该列数据对应的主键,在里面存储了一个书签(bookmark),该书签用来告诉InnoDB存储引擎哪里可以找到与索引相对于的行数,InnoDB存储引擎的辅助索引的书签就是相应行数据的聚集索引键,然后在根据聚集索引去查询数据,在MyISAM存储引擎中,聚集索引和非聚集索引中叶子节点存储的是都是数据的文件地址

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL采用B+树作为索引的原因 的相关文章

  • 使用MySQL计算单个表中借方和贷方的余额

    下面的 MySQL 表包含带有关联金额的借方或贷方 操作 如何选择具有非零 余额 的所有 CLIENT ID 我尝试将表连接到自身以计算所有借方和贷方总额 但有些东西无法正常工作 CLIENT ID ACTION TYPE ACTION A
  • 基本表创建 fpdf

    我找不到使用 fpdf 制作表格并从 mysql 数据库获取数据的合适教程 我只是想知道如何创建一个 我在网上尝试示例时遇到了很多错误 例如 我有 名字 中间名 姓氏 年龄 和 电子邮件 列 如何使用 fpdf 创建表格并回显数据库中的条目
  • PHP/MySQL:如何在网站中创建评论部分[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我不会问 如何使用 PHP MySQ
  • 如何在 join 语句中进行计数

    我有桌子post int post id varchar title text content和表comment int comment id int post id varchar content其中 post id 是外键引用表帖子 如
  • 哪个是识别关系或非识别关系中的子表?

    在表之间的识别和非识别关系的上下文中 MySQL 文档大量将表称为父表和子表 如何判断哪个表是父表 哪个表是子表 子表 A K A 弱实体 http en wikipedia org wiki Weak entity 是一个表 其主键属性d
  • 通过将行旋转为动态数量的列来在 MySQL 中创建摘要视图

    我在 MySQL 中有一个表 其中包含以下字段 id company name year state 同一客户和年份有多行 以下是数据示例 id company name year state 1 companyA 2008 1 2 com
  • 将 mysql LONGTEXT 值转换为 VARCHAR 值?

    我有一个在用户 Facebook 墙上发布的功能 我发送到 facebook 的一件事是我从设置为 LONGTEXT 的 mysql 表中获取的一些文本 如果我将表设置为 LONGTEXT 则文本不会发送到 facebook 但如果我将表设
  • MySQL 和 MariaDB 数据库有什么区别?

    我已经使用 XAMPP 很长时间了 很惊讶 XAMPP 已经从 MySQL 切换到了 MariaDB https www apachefriends org index html https www apachefriends org in
  • 如何在 MySQL 中创建查询以根据日期和独特字段减去连续行?

    基于SQL根据日期和另一列减去两行 https stackoverflow com questions 12310221 sql subtract two rows based on date and another column我有一个好
  • MySQL 中的 group_concat 性能问题

    我添加了一个group concat到一个查询并杀死了性能 添加之前和之后的解释计划是相同的 所以我对如何优化它感到困惑 这是查询的简化版本 SELECT curRow curRow 1 AS row number docID docTyp
  • 如何告诉node.js mysql没有在默认端口上运行?

    我遇到了与此人类似的问题 连接 ECONNREFUSED 节点 js sql https stackoverflow com questions 8825342 connect econnrefused node js sql 我正在尝试将
  • 更改“Mysql 行大小太大”的限制

    我如何更改限制 行大小太大 gt 8126 将某些列更改为 TEXT 或 BLOB 或使用ROW FORMAT DYNAMIC or ROW FORMAT COMPRESSED可能有帮助 在当前行格式中 BLOB768 字节的前缀内联存储
  • 使用 PHP 显示 Mysql 中的图像

    这就是我的数据库中的表的样子 我正在尝试显示我存储的图像 它是 mimetype longblob 当我运行代码时 它会给我一个带有 的小框 没有错误 只是那个框 有谁知道错误是什么以及如何修复它 Display Index Display
  • 重新启动我的 sql 时,jenkins 失败“sudo:不存在 tty,并且未指定 Askpass 程序 抱歉,请重试。”

    我刚刚配置了 jenkins 在预构建步骤中我尝试重新启动 jenkins 但最终出现以下错误 Commencing build of Revision c5b9f8daac092efc5396d80f568a2cf89ae8b697 or
  • 无法将包含数据的大型 CSV 文件转换为 mysql 数据库[重复]

    这个问题在这里已经有答案了 如何将大型文本文件转换为mysql数据库 文件大小3GB 1100万行 文件中的每一行都是这样的 1303179444 20 5811 Ahmed Al Emam male ahmed e alemam ahme
  • MySql 复合索引

    我们使用 MySql 作为我们的数据库 以下查询在 mysql 表 大约 2500 万条记录 上运行 我在这里粘贴了两个查询 查询运行得太慢 我想知道更好的复合索引是否可以改善这种情况 你知道最好的综合指数是什么吗 并建议我这些查询是否需要
  • MySQL 中的类型:BigInt(20) 与 Int(20)

    我想知道两者之间有什么区别BigInt MediumInt and Int是 很明显 它们会允许更大的数量 不过 我可以做一个Int 20 or a BigInt 20 这会让人觉得这并不一定与尺寸有关 一些见解会很棒 只是有点好奇 我一直
  • PDO 连接字符串:最好的方法是什么? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我想使用 php pdo 制作一个后端应用程序 我发现了很多不同的方法来处理 PDO 连接字符串 我想知道使用 pdo 执行连接字符串的最佳方法
  • 像搜索一样在mysql中包含空格

    我在某些情况下使用 mysql like 关键字时遇到问题 我的要求是这样的 首先 当我搜索时 ABC 结果应该找到ABC and ABCdef但不是xyzABCdef or xyzABC 乍一看使用起来很简单ABC 但在我搜索时的情况 h
  • 有什么方法可以在MySQL中的表名位置使用变量吗?

    我想在表名称位置使用变量 例如 SELECT FROM targetTableName 然而它会出错 有什么方法可以在MySQL中的表名位置使用变量吗 您显示的查询不起作用有两个原因 插入到查询中的用户定义变量将被视为使用字符串文字 而不是

随机推荐

  • keil5warning: function “xxxx” declared implicitly的bug分析

    keil5warning function xxxx declared implicitly的bug分析 一 问题分析 可能是头文件出错 自己不小心将两个文件的预编译指令 防止头文件被重复包含 名称写成相同的了 导致想要使用的函数原型声明的
  • Maven和Gradle如何添加依赖

    一 首先来看看Maven项目怎么添加依赖 二 上图中红圈部分的pom xml文件就是可以添加依赖的地方 例如这个 一定要放到 里面
  • 5号字对应的数字字号_字号对照表

    字号 磅数 宋体 黑体 楷体 初号 42 宋体初 黑体初 楷体初 小初 36 宋体小初 黑体小初 楷体小初 一号 26 宋体一号 黑体一号 楷体一号 小一 24 宋体小一 黑体小一 楷体小一 二号 22 宋体二号 黑体二号 楷体二号 小二
  • oracle学习之路(5)Navicat连接Oracle数据库:Oracle library is not loaded 解决方案

    Navicat连接Oracle数据库报错 Oracle library is not loaded 原因 这是因为OCI环境配置有问题 需要修改 oci dll 文件路径 版本不一致 是oci dll版本不对 因为Navicat是通过Ora
  • umi4学习 路由跳转 history useNavigate 的使用

    umi4 history 已经不用query传参了 接下来就来讲讲如何传参吧 第一种 适用于只跳转路径 不携带参数 import history from umi history push user 第二种 用于携带参数 并且参数很多的情况
  • 深度聚类相关(三篇文章)

    一 Deep Clustering for Unsupervised Learning of Visual Features 原文链接 https arxiv org pdf 1807 05520 pdf 完全不需要标签的无监督学习方法 好
  • navicat12,使用自动完成代码,没有默认选中第1个,怎么设置?

    navicat12 使用自动完成代码 没有默认选中第1个 怎么设置 按 TAB 插入第一个选项 ESC 代码提示
  • 【C++】Vector和String详解

    前言 没错 我又更新了 即使没人看 上一篇文章介绍了有关双向链表的容器list 那问题来了 数组和字符串这种使用频率非常高的数据结构 在STL模板中会不会有让人眼前一亮的实现哪 很明显 有 vertor和string就是这两种数据结构相对应
  • Python Flask 中的路由

    Python Flask 中的路由 在 Web 应用中 接口一般都是遵守 RESTful API 设计风格的 这种风格很优雅 而且对用户来说非常易于理解 RESTful API 参考 https blog csdn net weixin 4
  • C语言:电话号码字母排列

    这点B玩意写了一下午加一晚上 但是理解了回溯法也值了 具体解释我写在注释里 include
  • Linux iNode 双网卡,已解决: Zynq 7000 双网卡配置-内核DTS该如何配置 - Community Forums...

    问题 ETH0是通的 ETH1找不到PHY 连接到GMII2RGMII转换器时 找不到该设备 dts和vivado该如何配置 系统 Zynq 7Z015 Vivado 2018 3 内核 4 6 VIVADO工程如下 在内核设备树文件中 配
  • mysql重连次数_Yii2-Mysql重连机制

    背景 nsq消费进程中长时间消费不到数据 mysql设置的自动断开时间超过后 mysql自动断线 服务端报mysql gone away 这时需要捕获异常重连并重试 或者将长连接改为短连接也可以解决该问题 解决 配置项新增 db gt cl
  • python马士兵学习笔记

    前言 本篇文章是作者在B站学习python马士兵视频的笔记 之前章节的内容可参考https blog csdn net qq 43511094 article details 113062435 或https blog csdn net w
  • stat()函数:获取文件状态

    相关函数 fstat lstat chmod chown readlink utime 头文件 include
  • SQL Server 基础操作 (二) 创建用户并且为用户授权

    1 创建用户 右键点击登录名 新建登录名 2 设置管理员权限 进入 服务器角色 在右侧的服务器角色面板中 勾选public 服务器角色 说明 sysadmin 执行SQL Server中的任何操作 serveradmin 配置服务器设置 s
  • nodejs链接mysql报错_nodejs连接数据库报错

    ER NOT SUPPORTED AUTH MODE 报错详情 使用nodejs连接数据库时报错 Error ER NOT SUPPORTED AUTH MODE Client does not support authentication
  • Blockly概述

    原文地址 https developers google com blockly guides overview Blockly是一个用于Web Android IOS的可视化代码编辑器库 Blockly使用了相互关联的积木来表示表达代码中
  • ES 搜索22 (function_score 支持的衰减函数 linear、exp 和 gauss)

    衰减函数 很多变量都可以影响用户对于酒店的选择 像是用户可能希望酒店离市中心近一点 但是如果价格足够便宜 也愿意为了省钱 妥协选择一个更远的住处 如果我们只是使用一个 filter 排除所有市中心方圆 100 米以外的酒店 再用一个filt
  • 关于根轨迹对于控制系统的一点理解

    自动控制理论根轨迹的学习过程中 经常会遇到几个问题 为什么要用根轨迹法 为什么根轨迹法最终转化为调整增益K来反应系统的稳定性和动态性能 为什么根轨迹法用开环传递函数求解的却是闭环极点 盲目的借助于matlab进行根轨迹的计算和绘图 有时候往
  • MySQL采用B+树作为索引的原因

    MySQL采用B 树作为索引的原因 1 MySQL的索引结构是如何查询的 在MySQL中 存储的数据记录都是持久化到磁盘中的 数据包含索引和记录 当MySQL查询数据时 由于索引也是持久化在磁盘上面的 首先会从磁盘上读取索引到缓存中 然后再