0

0

深入聊聊mysql索引为什么采用B+树结构

青灯夜游

青灯夜游

发布时间:2021-09-28 19:52:03

|

2593人浏览过

|

来源于掘金社区

转载

本篇文章是mysql的进阶学习,介绍一下mysql使用b+树作为索引数据结构的原因,希望对大家有所帮助!

深入聊聊mysql索引为什么采用B+树结构

索引提高查询效率,就像我们看的书,想要直接翻到某一章,是不是不用一页一页的翻,只需要看下目录,根据目录找到其所在的页数即可。【相关推荐:mysql视频教程

在计算机中我们需要一种数据结构来存储这个目录,常见数据结构有哈希表,二叉查找树,二叉平衡树(AVL),红黑树,那为什么Innodb和MyISAM选择b+树呢。

1. 哈希表
哈希表就是一个数组+链表,用下标0,1,2,3..... 表示其数据所在的位置。如果想要在哈希表中存放数据,首先用对这个数据进行散列算法(基本的就是取模运算),假如数组长度是13 ,进行模13之后是0-12,正好对应的数据的下标,如果计算出的下标一样的,就会在下标位置跟上链表。

缺点:

  1. 利用hash存储需要将所有的数据文件添加到内存,比较消耗内存空间。
  2. hash的查找是等值查询,速度很快,但是各个数据间没有范围规律,但在实际工作中更多的是范围查询,hash就不太合适了。

不能直接说mysql不使用哈希表,而是要根据存储引擎来确定的,Memory存储引擎使用的就是哈希表

2. 二叉查找树

2.gif

缺点:

  1. 如图,极端情况可能会出现倾斜的问题,最后变成链表结构。
  2. 造成树节点过深,从而增加查找的IO,而现在IO就是查找的瓶颈
3. 二叉平衡树-AVL

为了保持树的平衡,避免出现数据倾斜,需要进行旋转操作,通过左旋或者右旋最终保持最长子树和最短子树长度不能超过1,如果超过1就不是严格意义上AVL树了

3.gif

缺点:

1.当数据量很大的时候,为了保持平衡,需要进行1-n次的旋转,这个旋转是比较浪费性能的,插入和删除效率极低,查询效率很高。

  1. 只有两个分支,数据量大的时候树的深度依然很深。
4. 红黑树

最长子树的不能超过最短子树的2倍,通过变色和旋转,在插入和查询上做了平衡

红黑树是avl树的变种,损失了部分查询性能来提高插入性能。

4.gif

缺点:

同样是只有两个分支,数据量大的时候深度依然会很深

以上三种二叉树,随着数据的增多,最终都会出现节点过多的情况,而且他们有且仅有2个分支,那么IO的次数一样很多.

怎么解决仅有2个分支而且深度过深,这就有了B树,增加分支

5. B-Tree
  1. 首先不读B减树,读B树
  2. 所有键值分布在整棵树中。
  3. 搜索有可能在非叶子结点结束,在关键字全集内做一次查找,性能逼近二分查找。
  4. 每个结点最多拥有m个子树。
  5. 根节点至少有2个子树。
  6. 分支节点至少拥有m/2棵子树(除根节点和叶子节点外都是分支节点)。
  7. 所有叶子节点都在同一层,每个节点最多可以有m-1个key,并且以升序排列

5.gif

Dora
Dora

创建令人惊叹的3D动画网站,无需编写一行代码。

下载

如上图:(图中只是画出来一部分,实际上没有限制的,不止p1,p2,p3)

每个节点占用一个磁盘块,一个节点上有两个升序排列的关键字和三个指向子树根节点的指针,指针存储的是子节点所在的磁盘块地址。两个关键词划分成的三个范围域对应三个指针指向的子树的数据的范围域。以根节点为例,关键字为16和34,p1指针指向的子树的数据范围小于16,p2指针指向的子树的数据范围为16-34,p3指针指向的子树的数据范围大于34。

查找关键字28的过程:

  1. 根据根节点找到磁盘块1,读到内存中。【第一次磁盘I/O操作】
  2. 比较关键字28在区间(16,34),找到磁盘块1的指针p2。
  3. 根据p2指针找到磁盘块3,读到内存。【第二次磁盘I/O操作】
  4. 比较关键字28在区间(25,31),找到磁盘块3的指针p2。
  5. 根据指针p2找到磁盘块8,读到内存。【第三次磁盘I/O操作】
  6. 在磁盘块8中的关键字列表中找到关键字28,结束。

缺点:

  1. 每个节点都有key,同时包含data,而每个页存储空间是有限的,如果data很大的话会导致每个节点能存储的key的数量变小。
  2. 当存储的数据量很大的时候会导致深度变大,增加查询磁盘的io次数,进而影响查询性能。
6. B+树

B+树是在B树的基础上做的一种优化,变化如下:

  1. B+树每个节点可以包含更多的节点,这个做的原因有两个,第一个原因是为了降低树的高度,第二个原因是将数据范围变成多个区间,区间越多,数据检索越快。
  2. 非叶子节点只存储key,叶子节点存储key和数据。
  3. 叶子节点两两指针互相连接(符合磁盘预读的特性),顺序查询性能更高。

6.gif

如上图: 在B+树上有两个头指针,一个指向根节点,另一个指向关键字的最小叶子节点,而且所有叶子节点(及数据节点)之间是一种链式环结构,因此可以对B+树进行两种查找运算:一种是对于主键的范围查找和分页查找,另一种是从根节点开始的随机查找。

InnoDB和MyISAM中索引上的差异

1. InnoDB-主键索引

叶子节点存储的是具体的行数据

7.gif

2. InnoDB-非主键索引

非主键索引的叶子节点存储的是主键值(所以查询数据基本要回表)

8.gif

3. MyISAM

叶子节点存储的是行数据的地址,额外需要一次寻址,多一次IO

9.gif

总结:为什么mysql使用的是B+树

准确的表述:为什么mysql的InnoDB和MyISAM存储引擎的索引使用的是B+树

  • hash表,等值查询是很快的,但是不满足常用的范围查找且相邻的两个值之间没有关系,而且hash比较消耗内存。

  • 二叉树/平衡二叉树/红黑树等都是有且仅有2个分支,共性就是数据量大的时候树的深度变深,增加IO的次数。

  • B树会在节点上存储数据,这样一页存放的key的数量就会减少,增加树的深度。

  • B+树中非叶子节点去除了数据,这样就会增加一页中key的数量,而且叶子节点之间是通过链表相连,有利于范围查找和分页。

原文地址:https://juejin.cn/post/6994810803643744269

作者:纪先生

更多编程相关知识,请访问:编程视频!!

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

16

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

23

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

75

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

95

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

218

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

420

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

168

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

222

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

33

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 2.5万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 847人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号