聊一聊MySQL的索引,MySQL索引为什么要选择B+树

mysql为什么要使用B+树作为索引 1 概述 大家可能在面试的时候都会被问到这样一个问题:mysql的索引结构是什么?这个时候了解的都知道是B+树,那么为什么会采用B+树作为它的索引结构呢? 由图可以知道:索引的存在时为了加快数据访问提高查询效率的,而数据存储在磁盘中,但从磁盘读取数据会产生大量的IO操作,读取效率是非常低的。所以在读取的时候要减少io量和减少io次数来提高读取效率。 ... 阅读详情

我们先了解一下什么是索引:

索引本质上就是一个数据结构,可以帮助我们更快的进行数据的查询。就像一本书前的目录一样,可以快速帮我们定位到我们要找的那一页。比如我们常见的散列表,在不发生哈希冲突的前提下,可以在O(n)的情况下完成数据的访问,插入和删除。还有一种比较常见的就是我们的二叉树,它可以在O(logN)的时间复杂度下完成数据的查找,但是在某些情况下二叉树会退化成链表,导致时间复杂度变为O(N);

我们再来了解一下使用MySQL进行数据读取的过程:

以 select * from user where id>5 为例,id为主键索引,那么搜索过程为:

存储引擎InnoDB --》 访问kernel --》进行磁盘IO(读取索引文件) --》 将数据加载到内存中 --》用索引的数据结构构建B+树加速搜索。

聚簇索引与非聚簇索引


接下来我们来聊一聊MySQL的聚簇索引和非聚簇索引。

在MySQL中,我们常用的存储引擎为MyISAM和InnoDB,它们的底层索引都是由B+树进行构建的,但是他们数据存储的方式却有所不同。

在InnoDB引擎下,数据和索引在磁盘中是存放在一起的,全部存放在xxx.idb文件下,而MyISAM的数据和索引是分开存储的,分别存储在xxx.myi和xxx.myd文件下,这也是为什么InnoDB要求表一定要有主键的原因,数据和索引是存储在一起的,没有主键索引就无法生成主键索引树。

因为索引和数据存放的位置不同,导致生成的索引树节点存放的数据不同。在InnoDB主键索引树的节点中key存放的就是主键,value就是主键对应的这一行数据本身。而在MyISAM中,因为索引和数据是分开存放的,所以key存放的是主键,value存放的是数据在内存中的地址。

像InnoDB这种key和数据本身存放在一起的称之为聚簇索引,像MyISAM这种value存放的不是数据本身的称之为非聚簇索引。

自适应hash索引


我们在上文提到过,使用哈希表(散列表)构成索引是非常鸡肋的,因为他会频繁的造成hash冲突,导致我们的搜索效率下降。在Java中的HashMap是使用数组+链表+红黑树来解决hash冲突的。

其实除了hash冲突之外,还有很多我们不使用hash索引的原因:

  1. 根据key使用hash算法生成的hashCode是随机的,也就是我们在存储数据时是没有任何顺序可言的,这也就导致我们无法使用where id > 5 这种范围查询和like模糊查询。

  1. 数据是存放在硬盘中的,每次读取数据都会进程磁盘IO,哈希表无法有效减少磁盘IO次数。

但这并不代表在MySQL中没有hash索引。memory存储引擎就是hash索引,InnoDB也有着自适应哈希索引。

当我们使用二级索引树(下文会提到)进行搜索时,如果我们频繁的使用上面的索引进行查找,那么MySQL就会自动为我们以二级索引树的key生成一个hash索引,用以加快等值查询时的速度。但这并不代表自适应hash索引效率是较高的。因为维护自适应hash索引也需要耗费性能。

  1. 自适应哈希索引会占用InnoDB的buffer pool

  1. RW-latch等待的线程数量,InnoDB默认设置了8个分区,可能会导致等待的线程数量过多,且当自适应hash索引命中略小于二级索引树时,我们就应该关闭自适应hash索引。

索引树


MySQL的索引树是选择使用B+树进行实现的。索引树分为两种,一种是主键索引树,顾名思义,是以主键作为key进行构建的索引树;一种是辅助(二级)索引树,是以非主键作为key进行构建的索引树。

我们给出一张表的字段:

id,userAccount,userPassowrd 三个字段,id为主键,userAccount为普通索引。

在构建主键索引树时,树节点的key为主键id,value为这一行数据本身。

在构建辅助索引树时,树的节点key为普通索引userAccount,value为主键id。当我们执行select * from user where userAccount = 'xxxxx' 时,MySQL就会构建辅助索引树,在辅助索引树上进行搜索。但是我们搜索的是select *,而在辅助索引树上是没有userPassowrd的,所以MySQL Server会拿着在辅助索引树上查到的key对应的主键id再去到主键索引树上进行查询,这种情况我们称之为回表。

为了避免回表现象,我们可以在只要id和userAccount时使用 select id, userAccount from user 这样的SQL语句进行查询,避免使用select * 出现回表。

在需要userAccount和userPassword时,也可以为userAccount和userPassword建立联合索引(多列),这样辅助索引树上的key就为userAccount和userPassword,就不会发生回表了。

为什么选择B+树


选择B+树肯定是经过对比发现B+树更为合适的,那么我们下面就对比这说一下B+树的优点,以及为什么不使用别的数据结构。

1. 为什么不适用AVL树

AVL树是二叉平衡树,它确实不会和二叉树一样退化为链表,但是它会有频繁的旋转。当插入一个新节点时旋转的复杂度还好,最多只需要一次旋转即可(单旋或者双旋);但是当删除数据导致树失衡时,需要维护从被删除节点到根节点这条路径上所有节点的平衡,旋转的量级为O(lgN)。

维护AVL树所带来的代价可能比它带来的好处更高。

2. 为什么不使用红黑树

红黑树是AVL树的变种,它并不要求严格的平衡,而是大致平衡。它给树的节点增加了颜色,红色或黑色。

红黑树舍弃了部分平衡性增强了在树失衡时旋转的效率,红黑树在删除或者新增节点时可以以O(1)的旋转次数保证树的平衡。但是因为不严格的平衡且一个节点只能保存一组key,value导致树会变得很高。我们知道MySQL的数据是存放在磁盘中的,所以它不能有效的解决磁盘IO效率问题。

但是在数据保存在内存中,红黑树是非常适合的,比如Java的HashMap就是使用数组+链表+红黑树进行构建的。

3. 为什么不使用B树

B树是为了磁盘而生的。

B树又称为多阶平衡查找树,它的非叶子节点可以有m个子树,m通常为300-500。这样的话树就会变矮许多,可以增强磁盘IO效率。

B树的优势除了树比较矮壮,还有对访问局部性原理的利用。所谓局部性原理,是指当一个数据被使用时其附近的数据有较大概率在短时间内被使用。B 树将键相近的数据存储在同一个节点,当访问其中某人数据时,数据库会将该整个节点读到缓存中,当它临近的数据紧接着被访问时,可以直接在缓存中读取,无需进行磁盘IO;换句话说,B 树的缓存命中率更高。

但是B树也是存在问题的:

  1. 搜索效率不确定,搜索普通节点和叶子节点的查找效率不稳定。

  1. 不适合范围查询,做范围查询时需要遍历整棵树,导致效率下降。

  1. 在节点中存放key和value,value会占用节点较多的空间,导致存放的key变少

为了解决上述问题,我们引进了B树的变种B+树。

4. 为什么选择B+树

我们先来说一下B+树的特点:

  1. 非叶子节点中只存放key,而不存放value

  1. value全部存放在叶子节点上,并且叶子节点之间有双向链表可以互相指向。

  1. 在叶子节点上保存的数据也是有顺序的

根据上述特点B+树比B树更适合作为MySQL的索引结构。

B+树的有点:

  1. 更少的磁盘IO次数,树更加矮状,因为非叶子节点中不需要存放value,可以存放更多的key。

  1. 支持范围查询和like模糊查询,因为叶子节点有序且可以互相指向。

  1. 更稳定的查找效率,因为所有的数据都存放在叶子节点中。

建立索引时需要考虑什么


  1. 首先肯定是为我们经常用来作为查询条件的字段设置索引

  1. 对经常需要排序,分组和联合操作的字段设置索引,防止在排序时出现file sort。

  1. 建立索引时按照最左匹配原则进行添加,不然有可能会使索引失效。

  1. 不要一味的增加过多索引,因为索引本身也会占存储空间,需要维护。

  1. 增加索引时要考虑索引的长度,不要为长度太长的字段添加索引,不然会降低索引的效率。

索引失效


  1. 第一肯定是没有遵守最左匹配原则。

  1. 在where后使用or,或在like模糊查询时用%xx开头。使用xx%结尾不会使索引失效。

  1. 如果索引使字符串类型,一定要用' '引起来,不然会MySQL会将字符串隐式转换为整形,导致索引失效。

  1. 如果全盘扫描的速度与索引扫描相差无几,就没必要添加索引,比如对一些枚举值添加索引。MySQL Server会自动使用全盘扫描。

Mysql索引结构全维度比较 前言 在MySQL中,无论是Innodb还是MyIsam,都使用了B+树作索引结构(这里不考虑hash等其他索引)。本文将从最普通的二叉查找树开始,逐步说明各种树解决的问题以及面临的新问题,从而说明MySQL为什么选择B+树作为索引结构。 一、二叉查找树(BST):不平衡 二叉查找树(BST,Binary Search Tree),也叫二叉排序树,在二叉树的基础上需要满足:任意节点的左子树上所有节... 阅读详情

相关推荐

MySQL为什么选择B+树作为索引数据结构?

有序性的特点使得B+树在范围查询和排序操作上具有良好的性能,可以快速定位到指定范围内的数据。相比于二叉查找树,B+树在同样的高度下可以容纳更多的数据,减少了磁盘I/O的次数,提高了查询速度。这样的平衡性质使得B+树的高度相对较低,查询时需要的磁盘I/O次数较少,从而提高了查询效率。综上所述,B+树在有序性、高度平衡、多路查找和叶子节点顺序访问等方面都具有优秀的性能表现,正是这些特点使得MySQL选择B+树作为索引的数据结构。索引是数据库中用于提高查询性能的重要机制,而B+树是一种常用的索引数据结构。

VcyReact的博客 429

mysql为什么使用b+树

MySQL 使用 B 树有以下几个原因: 查询效率高:B 树的查询时间复杂度是 log(n) 级别的,相比链表和二叉树的 O(n),性能要高得多。 支持范围查询:B 树能够支持范围查询,这在 MySQL 中经常用于 WHERE 子句中的 BETWEEN 和 IN 运算符。 支持索引和排序:B 树可以用来实现索引,而且在查询时能够保证结果的有序性。 支持动态扩展:B 树可以动态地向两侧扩展,...

weixin_42588555的博客 2075

Vienna整流器双PI闭环仿真:从SVPWM调制到中点电位平衡的实践解析

本文深入解析Vienna整流器双PI闭环仿真技术,涵盖SVPWM调制和中点电位平衡的实践细节。通过详细的MATLAB/Simulink仿真搭建流程和常见问题排查方法,帮助工程师掌握高效整流器控制策略,提升系统稳定性和动态响应性能。

weixin_29168153的博客 323

mysql为什么要用b+树

mysql为什么要用b+树

qq_40263124的博客 6229

基于FPGA的图像预处理系统(图)

 北京机械工业学院 韩娟娟 邓文怡 娄小平 由于获取图像的工具或手段的影响,使获取图像无法完全体现原始图像的全部信息。因此,对图像进行预处理就显得非常重要。预处理的目的是改善图像数据,抑制不需要的变形或者增强某些对于后续处理来说比较重要的图像特征。通常根据预处理目的的不同,把预处理技术归为图像增强技术和图像分割技术两类。图像对比度处理是空间域图像增强的一种方法。由于图像灰度范围狭窄会使

lyzhangxianglove的专栏 1777

SCI、中科院1区算法应用:(BWO-CNN-BiGRU-Attention)白鲸优化深度学习-融合注意力机制预测程序代码!包含特征可视化,数据Excel导入,直接运行!

BWO 白鲸优化算法,于2022年发表在SCI、中科院1区期刊《Knowledge-Based Systems》上。我们利用该高创新算法对我们的CNN-BiGRU-Attention时序和空间特征结合-融合注意力机制的回归预测程序代码中的超参数进行优化。

weixin_48747334的博客 3250

为什么 MySQL 采用 B+ 树作为索引?

为什么 MySQL 采用 B+ 树作为索引? 文章目录为什么 MySQL 采用 B+ 树作为索引?怎样的索引的数据结构是好的?什么是二分查找?什么是二分查找树?什么是自平衡二叉树?什么是 B 树什么是 B+ 树?1、单点查询2、插入和删除效率3、范围查询MySQL 中的 B+ 树总结结语 要解释这个问题,其实不单单要从数据结构的角度出发,还要考虑磁盘 I/O 操作次数,因为 MySQL 的数据是存储在磁盘中的嘛。 这次,就跟大家一层一层的分析这个问题,图中包含大量的动图来帮助大家理解,相信看完你就拿捏这道题

猫头虎技术团队:授渔优于赠鱼,兴趣引领智慧,探索之乐尤显珍贵。商务合作+:Libin9iOak ,万粉变现+:CSDNWF,猫头虎承诺每年免费为100名C站创作者做账号流量诊断服务!全网搜:猫头虎技术团队,点击文章底部名片或直接私信我一切皆可谈,快找虎哥! 7880

LittleFS+NANDFLASH软硬件配置详情

littleFS文件系统说明及移植过程

weixin_43200844的博客 2355

为什么MySql索引使用B+树

前言 面试中我们经常碰到面试官问到数据库索引,问到索引就会问你索引的数据结构。类似这种数据结构对于普通程序员来说记住概念几天就忘了,而且概念不是每个人都能很好都理解,所以针对这一原因,我简单通俗都像大家讲解为什么mysql使用都是B+树,而不用其他的树形结构。 正文 Q1:B+树的查询时间大概多少? A:跟树的高度有关,是O(log n)。 Q2:hash查找时间大概多少? A:o(1...

晏霖/胖虎的博客 1万+

Cadence17.2 > Allegro > 检查PCB Layout信号线组等长

Cadence17.2 > Allegro > 检查PCB Layout等长和配线

DL_62532的专栏 1万+

ABAP 里的 XML 与 JSON 处理,一套从接口落地到 Clean Core 的完整参考

ABAP 里的 XML 和 JSON 处理并不只是几段工具类调用。iXML、sXML、、XCO、、code page conversion、GZIP、对象序列化,这些能力背后对应的是不同的数据规模、访问模式、接口契约和运行时边界。小报文、复杂树结构、需要修改节点,iXML 很顺手。大报文、顺序读写、内存敏感,sXML 更可靠。ABAP 结构和 XML、JSON 之间要做标准转换,是主干。现代 JSON API、ABAP Cloud、命名转换,XCO 值得优先考虑。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 215

为什么 MySQL 选择使用 B+ 树作为索引结构?

MySQL选择B+树作为索引结构,是因为B+树能够在磁盘存储环境中提供高效的查询性能。它的自平衡特性、支持高效的范围查询、减少磁盘I/O操作以及能够处理大规模数据集的能力,使其成为关系数据库索引的理想选择。B+树在处理频繁的增删改查操作、提高数据访问速度以及范围查询时表现出色,这些特点都符合MySQL数据库系统的需求。高效的范围查询:B+树是一种自平衡的树结构,所有的叶子节点都在同一层,因此支持高效的范围查询。

Weiki的博客 2186

数学建模学习(75):全局敏感性分析Morris 方法

敏感性分析 (SA) 是分析不同应用条件下模型行为的基本实践。提出了许多 SA 技术,从简单的筛选方法到计算成本高昂的基于方差的方法。本篇内容我们通过将 Morris 方法来对模型进行分析。

全栈川川 1万+

MySQL底层为什么选择用B+树作为索引

跳表底层实质就是可以进行二分查找的有序链表。而且在链表基础加上索引层。即能支持插入、删除等动态操作,也支持按区间高效查询。而且不管是查找、插入、删除对应的时间复杂度都是O(logn)。要理解跳表,先来看链表,假设链表存储是有序的数据,我们要想查询某一个数据,在最差的情况下要从头全遍历整个链表,时间复杂度是O(n)。从上图所示,我们如果要查询一个26的节点,跳表就可以先从索引层遍历,当遍历到在索引层的21节点,会发现下一个索引层的节点是36节点时,很明显要找的26的节点就在这区间。

qq_71416673的博客 1615

【异常】Claude Code 第三方API 400报错(thinking type should be enabled or disabled)解决方案

摘要: Claude Code接入第三方API端点时出现400参数错误,主要因新版默认启用的Adaptive Thinking功能与旧版接口参数格式不兼容(需thinking: {type: "adaptive"},但第三方仅支持布尔值)。解决方案为修改本地settings.json配置文件,添加"CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING": "1"环境变量并重启客户端,即可恢复思考模式功能。Adaptive Th

奶爸的编程之路,也就一周冷个三天 1万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

为什么Mongodb索引用B树,而Mysql用B+树?

引言好久没写文章了,今天回来重操旧业。今天讲的这个主题,是《面试官:谈谈你对mysql索引的认识》,里头提到的一个坑。也就是说,如果面试官问的是,为什么Mysql中Innodb的索引结构...

孤独烟 3988

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

面试官:MySQL 为什么用 B+ 树实现索引

MySQL 为什么用 B+ 树实现索引索引概述常见的索引模型哈希表有序数组二叉查找树二叉查找树的查找操作二叉查找树的缺陷为什么索引不用二叉树实现InnoDB 的索引模型B 树B 树存在的问题B+ 树B 树 和 B+ 树 的区别总结 索引对大家来说肯定不会陌生,不管是日常的开发还是面试中,都少不了索引的身影。 我们都会使用索引,但是我们对于索引的原理却是一知半解。本文就带大家深入学习一下 MySQL 的索引模型。 索引概述 关于索引的定义,百度百科给出的解释是: 在关系数据库中,索引是一种单独的、物理的对数

xujunson的博客 5355

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

【MySQL系列1】MySQL索引为何选择B+树

MySQL为何选择B+树存储索引声明什么是索引二分查找法(Binary Search)二叉查找树(BST)二叉树的特点二叉树存在的问题平衡二叉树(AVL Tree)平衡二叉树的特点MySQL为何不选择平衡二叉树索引需要存储什么AVL树用来存储索引存在什么问题多路平衡树(Balanced Tree)B树的特点B树是如何查找数据的B+树B+树的特点B+树是如何查找数据的B+树相对于B树的改进点总结 声明 本文所述的各种数据结构(二叉树等),均不考虑重复值的情况,本文简述各种数据结构的区别仅仅只是为了理解MySQ

zwx900102的博客 3754

MySQL 索引:索引为什么使用 B+树?(详解B树、B+树)

本文探讨了MySQL选择B+树作为索引结构的原因。首先分析了二叉查找树(BST)可能退化为链表导致查询效率下降的问题,进而引入平衡二叉树(AVL)和红黑树,指出AVL旋转耗时、红黑树虽然性能更优但树高仍然过高的问题。特别针对磁盘存储场景,提出树高过高会导致IO次数增加,影响性能。通过对比哈希索引和二分查找的优缺点,指出二叉查找树在磁盘存储中的局限性,最终说明B+树因其矮胖特性、减少IO次数、支持范围查询等优势,成为数据库索引的理想选择。

Atticus的博客 2163

MYSQL-索引结构介绍、为什么选择B+树而不是B树

看了很多讲B树和B+树的文章,大多都是围绕各自的特性讲的,第一,树中每个结点最多含有m个孩子(m>=2);第二,……我也是从这些文章里弄懂了各种树的联系与区别,要真写,我可能还不如人家写得好。所以就在这里简明扼要的用几张图记录一下主要区别吧。 为了便于说明,我们先定义一条数据记录为一个二元组[key,data],key为记录的键值,key唯一;data为数据记录除key外的数据。 ...

z69183787的专栏 2万+

MySQL为什么选择B+树

在我们日常开发中,MySQL 用得最多的存储引擎是 InnoDB,而它默认的索引结构就是B+树(B+Tree)。那么问题来了:✅ 为什么不是哈希表?✅ 为什么不是二叉树?✅ 为什么不是B树而偏偏是B+树?这篇文章,深入浅出MySQL 为什么选择了 B+树?指标是否满足?说明快速定位✅多叉树+低层级范围查询✅叶子节点链表遍历支持排序✅中序遍历天然有序IO友好✅每个节点可对应一个磁盘页插入删除效率✅平衡性强,节点分裂/合并机制成熟。

大西瓜的博客 1660

二叉树、B树(B-树)、B+树、B*树详解,以及为什么MySQL选择B+树做索引

温故而知新,可以为师矣。看到一篇介绍B数和B减树的文章,这里记录一下。 1. 简要 众所周知,MySQL的索引使用了B+树的数据结构。那么为什么不用B树呢? 先看一下B树和B+树的区别。 2. 二叉树 先介绍一下二叉搜索树。 顾名思义,二叉搜索树,即指最多拥有两个叉,这里的叉即为所有非叶子结点的儿子(Lift和Right); 所有的结点存储一个关键字; 非叶子结点的左指针指向小于其关键字的结点,右指针指向对于其关键字的结点,结构如下图: 二叉搜索树的搜索,从根结点开始,如果查询的关...

zzhongcy的专栏 4424

MySQL索引底层结构为什么选择B+树

MySQL官网介绍:索引是帮助mysql高效获取数据的排好序的数据结构。简而言之,索引本质是一种优化查询的数据结构。 比较如下一些数据结构的索引,就可以发现其中的缘由。 1.Hash索引 Hash索引把数据以hash形式组织起来,因此查找某一条记录的时候,速度非常快。同时.hash算法的索引有个缺点,因为它不是按照大小排序的。所以,它无法按照范围进行查找。 2.二叉树结构索引 二叉树的定义: 1...

qq_35529931的博客 7841

为什么MySQL数据库索引选择使用B+树

为什么MySQL数据库索引选择使用B+树1.前言-介绍各种树2.B/B+树3.为什么B+树比B树更适合数据库的索引?4.数据库的索引类型 1.前言-介绍各种树 1.二叉查找树:即有序二叉查找树,二叉搜索树; 对于某些情况,二叉查找树会退化成一个有n个节点的线性链;查找效率就很低了; 2.平衡二叉树(AVL):即带有平衡条件的二叉查找树,一般是用平衡因子差值判断是否平衡并通过旋转来实现平衡,左...

107 9957

mysql为什么选择B+树作为索引结构

mysql为什么选择B+树作为索引结构

m0_54258715的博客 1494
上一篇: 为什么在数据库中不推荐使用外键?
下一篇: 聊一聊MySQL的事务
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值