当前位置:首页 > 文章列表 > 数据库 > MySQL > 深入理解MySQL索引底层数据结构

深入理解MySQL索引底层数据结构

来源:51cto 2023-05-01 14:56:14 0浏览 收藏

编程并不是一个机械性的工作,而是需要有思考,有创新的工作,语法是固定的,但解决问题的思路则是依靠人的思维,这就需要我们坚持学习和更新自己的知识。今天golang学习网就整理分享《深入理解MySQL索引底层数据结构》,文章讲解的知识点主要包括MySQL、索引、底层数,如果你对数据库方面的知识点感兴趣,就不要错过golang学习网,在这可以对大家的知识积累有所帮助,助力开发能力的提升。

作者:京东物流 于朔

1 引言

在日常工作中,我们会遇见一些慢SQL,在分析这些慢SQL时,我们通常会看下SQL的执行计划,验证SQL执行过程中有没有走索引。通常我们会调整一些查询条件,增加必要的索引,SQL执行效率就会提升几个数量级。我们有没有思考过,为什么加了索引就会能提高SQL的查询效率,为什么有时候加了索引SQL执行反而会没有变化,本文就从MySQL索引的底层数据结构和算法来进行详细分析。

2 索引数据结构对比

索引的定义:索引(Index)是帮助MySQL高效获取数据的排好序的数据结构。

索引中常见的数据结构有以下几种:

  • Hash表
  • 二叉树
  • 红黑树
  • B-Tree
  • B+Tree

Hash表通过索引的key进行一次hash计算,就可以快速获取磁盘文件指针,对于指定索引查找文件非常快,但是对于范围查找没法支持,有时候也会出现Hash冲突的情况。

深入理解MySQL索引底层数据结构

二叉树二叉树的特点:左边子节点的数据小于父节点数据,右边子节点的数据大于父节点数据。如下图所示,如果col2是索引,查找索引为65的行元素,只需要查找两次,就可以获取到行元素所在的磁盘指针地址。

深入理解MySQL索引底层数据结构

但如果是一个按照顺序递增的值,例如为col1建立索引,不再适合使用二叉树建立索引,因为此时使用二叉树建立索引将会变成一个链式索引,此时的索引结构如下图所示,如果查找6节点需要6次遍历才能找到。

深入理解MySQL索引底层数据结构

红黑树红黑树是一种二叉平衡树,可以提高查询效率,此时若再查找6节点只需要遍历3次就能找到了。但红黑树也有缺点,当存储大数据量时,树的高度就会变的不可控, 数量越大,树的高度越高,查询的效率将会大大降低。

深入理解MySQL索引底层数据结构

B-TreeB-Tree是一种多路二叉树,所具有的特点:1 叶节点具有相同的深度,叶节点的指针为空;2 所有索引元素不重复;3 节点中的数据索引从左到右递增排列。

深入理解MySQL索引底层数据结构

B+TreeB+Tree是B-Tree的变种,所具有的特点:1 非叶子节点不存储data,只存储索引(冗余),可以放更多的索引;2 叶子节点包含所有索引字段;3 叶子节点用指针连接,提高区间访问的性能。

深入理解MySQL索引底层数据结构

与红黑树相比,B-Tree和B+Tree两种数据结构都更加矮胖,存储相同数量级的索引数据时,层级更低。

B-Tree和B+Tree之间一个很大的不同,是B+Tree的节点上不储存value,只储存key,而叶子节点上储存了所有key-value集合,并且节点之间都是有序的。这样的好处是每一次磁盘IO能够读取的节点更多,也就是树的度(Max.Degree)可以设置的更大一些,因为每次磁盘IO读取的磁盘页数是一定的。例如,每次磁盘IO能够读取1页=4kb,那么省去value的情况下同样一页数据能够读取更多的key,这样就大大减少了磁盘的IO次数。

此外,B+Tree也是排好序的数据结构,数据库中>

MySQL中对于索引使用的主要数据结构也是B+Tree,目的也是在读取数据时能够减少磁盘IO。

3 千万级数据如何用B+树索引快速查找

MySQL 官方对非叶子节点(如最上层 h = 1的节点,B+Tree高度为3) 的大小是有限制的,最大的大小是16K,可以通过以下SQL语句查询到,当然这个值是可以调的,既然官方给出这个阈值说明再大的话会影响磁盘IO效率。

深入理解MySQL索引底层数据结构

从执行结果,可以看到大小为 16384,即 16K大小。

假如:B+Tree的表都存满了。主键索引的类型为BigInt,大小为8B,指针存储了下个节点的文件地址,大小为6B。最后一层,假如 存放的数据data为1K 大小,那么

  1. 第一层最大节点数为: 16k / (8B + 6B) ≈ 1170 (个);
  2. 第二层最大节点数也应为:1170个;
  3. 第三层最大节点数为:16K / 1K = 16 (个)。

则,一张B+Tree的表最多存放 1170 1170 16 ≈ 2千万。

深入理解MySQL索引底层数据结构

所以,通过分析,我们可以得出,B+Tree结构的表可以容纳千万数据量的查询。而且一般来说,MySQL会把 B+Tree 根节点放在内存中,那只需要两次磁盘IO就行。

4 存储引擎索引实现

MySQL中索引储存在哪里呢?和数据一样,索引以文件形式储存在硬盘上。
在MyISAM储存引擎中,数据和索引文件试试分开储存的,数据存在.MYD结尾的文件中,索引单独存在.MYI结尾的文件中。

深入理解MySQL索引底层数据结构

在InnoDB中,数据和索引文件是合起来储存的,注意下图中没有了.MYI结尾的文件,只有一个.ibd结尾的文件。

深入理解MySQL索引底层数据结构

MyISAM索引文件和数据文件是分离的(非聚集),并且主键索引和辅助索引(二级索引)的储存方式是一样的。

深入理解MySQL索引底层数据结构

深入理解MySQL索引底层数据结构

InnoDB中索引文件和数据文件是同一个文件(聚集),并且主键索引和二级索引储存方式有所不同,如图所示,二级索引的叶子节点不储存数据,仅储存主键ID。

深入理解MySQL索引底层数据结构

深入理解MySQL索引底层数据结构

这里思考几个问题:

  • 为什么建议InnoDB表必须建主键,并且推荐使用整型的自增主键?
  • 为什么非主键索引结构叶子节点存储的是主键值?

如果我们在创建表时不设置主键,InnoDB会自动帮我们从第一列开始筛选一列数据不重复的列做为主键,如果找不到这样的列,就会创建一个隐藏的列(rowid)做为主键,这会增加很多MySQL的工作,所以建议我们在创建InnoDB表时一定要设置主键。

整型的字段做为主键,一方面在数据比较时不需要进行转换,另一方面存储也比较节省空间。那为什么要强调主键自增呢?如果主键id是无序的,那么很有可能新插入的值会导致当前节点分裂,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。反之,如果每次插入有序,那就会在当前页后面连续写入,写不下就会重新分配一个节点,内存都是连续的,这样效率自然也就最高了。

非主键索引的叶子节点存储主键值而非全部数据,主要也是为了一致性和节省空间。如果二级索引储存的也是数据,那么每次插入MySQL都不得不更新每棵索引树,这样就加剧了新增编辑时的性能损耗,并且这样一来空间利用率也不高,必然产生了大量冗余数据。

5 联合索引底层数据结构又是怎样的

联合索引又叫复合索引,例如下表:

CREATE TABLE `test` ( `id` bigint NOT NULL AUTO_INCREMENT, `name` varchar(24) NOT NULL, `age` int NOT NULL, `position` varchar(32) NOT NULL, `address` varchar(128) NOT NULL, `birthday` date NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `idx_name_age_position` (`name`,`age`,`position`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

如下索引就是一个联合索引。

`idx_name_age_position` (`name`,`age`,`position`) USING BTREE

联合索引底层数据结构长什么样?

深入理解MySQL索引底层数据结构

比较相等时,先比较第一列的值,如果相等,再继续比较第二列,以此类推。

了解了联合索引的存储结构,我们就知道了索引最左前缀优化原则是怎么回事了,在使用联合索引时,对于索引列的定义顺序将会影响到最终查询时索引的使用情况。例如联合索引(name,age,position),MySQL会从最左边的列优先匹配,如果最左边的带头大哥name没有使用到,在未使用覆盖索引的情况下,就只能全表扫描。

联合底层数据结构思考:MySQL会优先以联合索引第一列匹配,此后才会匹配下一列,如果不指定第一列匹配的值,也就无法得知下一步查询哪个节点。

6 总结

索引本质上是一种排好序的数据结构,了解了MySQL索引的底层数据结构及存储原理,可以帮助我们更好地进行SQL优化。其实数据库索引调优是一项技术活,不能仅仅靠理论,因为实际情况千变万化,而且MySQL本身存在很复杂的机制,如查询优化策略和各种引擎的实现差异等都会使情况变得更加复杂。但同时这些理论是索引调优的基础,只有在明白理论的基础上,才能对调优策略进行合理推断并了解其背后的机制,然后结合实践中不断的实验和摸索,从而真正达到高效使用MySQL索引的目的。

最后,如果大家想再温习一下数据结构的知识,这个数据结构网站(https://www.cs.usfca.edu/~galles/visualization/Algorithms.html )不可错过,可以很好地帮助我们演示数据结构的存储过程。

到这里,我们也就讲完了《深入理解MySQL索引底层数据结构》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于mysql的知识点!

版本声明
本文转载于:51cto 如有侵犯,请联系study_golang@163.com删除
mysql有什么外键约束等级mysql有什么外键约束等级
上一篇
mysql有什么外键约束等级
Redis+DB实现基于号段的发号器原理
下一篇
Redis+DB实现基于号段的发号器原理
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 笔灵AI生成答辩PPT:高效制作学术与职场PPT的利器
    笔灵AI生成答辩PPT
    探索笔灵AI生成答辩PPT的强大功能,快速制作高质量答辩PPT。精准内容提取、多样模板匹配、数据可视化、配套自述稿生成,让您的学术和职场展示更加专业与高效。
    12次使用
  • 知网AIGC检测服务系统:精准识别学术文本中的AI生成内容
    知网AIGC检测服务系统
    知网AIGC检测服务系统,专注于检测学术文本中的疑似AI生成内容。依托知网海量高质量文献资源,结合先进的“知识增强AIGC检测技术”,系统能够从语言模式和语义逻辑两方面精准识别AI生成内容,适用于学术研究、教育和企业领域,确保文本的真实性和原创性。
    22次使用
  • AIGC检测服务:AIbiye助力确保论文原创性
    AIGC检测-Aibiye
    AIbiye官网推出的AIGC检测服务,专注于检测ChatGPT、Gemini、Claude等AIGC工具生成的文本,帮助用户确保论文的原创性和学术规范。支持txt和doc(x)格式,检测范围为论文正文,提供高准确性和便捷的用户体验。
    30次使用
  • 易笔AI论文平台:快速生成高质量学术论文的利器
    易笔AI论文
    易笔AI论文平台提供自动写作、格式校对、查重检测等功能,支持多种学术领域的论文生成。价格优惠,界面友好,操作简便,适用于学术研究者、学生及论文辅导机构。
    38次使用
  • 笔启AI论文写作平台:多类型论文生成与多语言支持
    笔启AI论文写作平台
    笔启AI论文写作平台提供多类型论文生成服务,支持多语言写作,满足学术研究者、学生和职场人士的需求。平台采用AI 4.0版本,确保论文质量和原创性,并提供查重保障和隐私保护。
    35次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码