深入理解MySQL InnoDB中的B+索引机制

news2024/9/23 10:28:04

目录

一、InnoDB中的B+ 树索引介绍

二、聚簇索引

(一)使用记录主键值的大小进行排序

 页内记录排序

页之间的排序

目录项页的排序

(二)叶子节点存储完整的用户记录

 数据即索引

自动创建

(三)聚簇索引的优缺点

三、二级索引

(一)二级索引的特点

基于非主键列排序

叶子节点存储部分数据

(二)二级索引的工作流程

(三)二级索引的优缺点

四、联合索引

(一)联合索引的特点

多列排序规则

联合索引的组成

(二)联合索引与单列索引的区别

联合索引

单列索引

(三)联合索引的优缺点

(四)联合索引的使用建议

五、总结

 参考文献、书籍及链接


干货分享,感谢您的阅读!

在现代数据库系统中,索引是提高数据检索速度的关键机制之一。InnoDB作为MySQL的默认存储引擎,采用了高效的B+树结构来实现其索引功能。这种结构不仅确保了数据的快速检索,还支持高效的插入、更新和删除操作。理解InnoDB中的B+树索引对于数据库优化和性能调优至关重要。

为了更好地理解 InnoDB 中 B+ 树索引的工作机制,我们从创建一个示例表index_demo开始,并通过详细的示意图展示记录在页中的存储结构及索引的作用。

CREATE TABLE index_demo (
    c1 INT,
    c2 INT,
    c3 CHAR(1),
    PRIMARY KEY (c1)
) ROW_FORMAT = Compact;

这个表中有两个 INT 类型的列 c1c2,一个 CHAR(1) 类型的列 c3,并且 c1 列为主键。表的行格式为 Compact。其基础可见:

一、InnoDB中的B+ 树索引介绍

B+ 树索引是一种自平衡的树结构,其节点分为内部节点和叶子节点:

  • 内部节点(Internal Nodes):用于索引导航,存储键值和指向子节点的指针。
  • 叶子节点(Leaf Nodes):存储实际的数据记录或指向数据记录的指针(称为记录指针)。

在 B+ 树中,所有的数据记录都存储在叶子节点中,而内部节点仅用于存储键值和导航信息。

不论是存放用户记录的数据页,还是存放目录项记录的数据页,我们都把它们存放到B+树这个数据结构中,所以我们也称这些数据页为节点。

从图中可以看出来,我们的实际用户记录都存放在B+树的最底层的节点上,这些节点也被称为叶子节点或叶节点,其余用来存放目录项的节点称为非叶子节点或者内节点,其中B+树最上面的那个节点也称为根节点。

依据InnoDB存储引擎B+树的树高推导当树高为4时,可以存放200百多亿行数据。这样的数据容量,可以满足绝大部分应用的需求,因此我们可以说在绝大部分应用中,B+树高度为3或4就可以满足数据存储的需求。B+树这种高扇出低树高的特征,也大大的提高了主键查询性能。

二、聚簇索引

在InnoDB存储引擎中,聚簇索引(Clustered Index)是数据存储和索引的一种特殊而重要的结构。聚簇索引主要特点:

(一)使用记录主键值的大小进行排序

聚簇索引通过主键值对记录和页进行排序,这涉及三个方面:

 页内记录排序

在每个页内,记录按照主键值的大小顺序排成一个单向链表,确保了页内记录的有序性,方便快速查找。页内的记录被划分成若干个组,每个组中主键值最大的记录在页内的偏移量会被当作槽依次存放在页目录中(当然Supermum记录比任何用户记录都大),我们可以在页目录内通过二分法定位到主键列等于某个值的记录。

页之间的排序

存放用户记录的页按照页内记录的主键大小顺序排成一个双向链表。这种结构使得范围查询和顺序扫描更加高效。

目录项页的排序

存放目录项记录的页根据页内目录项记录的主键大小顺序排成一个双向链表。不同层次的页同样遵循这种排序规则,确保树的平衡性和查询效率。 

(二)叶子节点存储完整的用户记录

B+树的叶子节点存储的是完整的用户记录,即包括所有列的值(包括隐藏列),在InnoDB中,叶子节点不仅仅是索引,还包含了实际的数据记录。这种特性使得聚簇索引与普通索引有所不同。

数据即索引 

聚簇索引中的叶子节点存储了完整的用户记录,因此聚簇索引就是数据的存储方式。换句话说,索引即数据,数据即索引。

自动创建

在InnoDB存储引擎中,聚簇索引会自动为每个表创建,并且不需要在MySQL语句中显式使用INDEX语句去创建。通常情况下,聚簇索引是基于表的主键创建的。 

(三)聚簇索引的优缺点

聚簇索引的优点聚簇索引的缺点
快速数据访问:由于数据和索引存储在一起,基于主键的查询非常高效,不需要额外的索引查找。插入和删除成本较高:由于需要维护数据的有序性,插入和删除操作可能需要移动大量记录,导致性能开销。
有序数据存储:记录按照主键顺序存储,适合范围查询和顺序扫描,提高查询性能。更新成本较高:如果更新操作导致主键变化,会引发记录的重新定位和页的重新排序,影响性能。

聚簇索引是InnoDB存储引擎中一种关键的索引类型,通过主键排序和存储完整用户记录,提供了高效的数据访问和有序的数据存储。在优化数据库性能时,理解和合理使用聚簇索引可以显著提升查询和数据操作的效率。具体优化可见:MySQL索引性能优化分析。

三、二级索引

聚簇索引只能在搜索条件是主键值时才能发挥作用,因为B+树中的数据都是按照主键进行排序的。那如果我们想以别的列作为搜索条件该咋办呢?难道只能从头到尾沿着链表依次遍历记录么?不,我们可以多建几棵B+树,不同的B+树中的数据采用不同的排序规则。比方说我们用c2列的大小作为数据页、页中记录的排序规则,再建一棵B+树,效果如下图所示:

在InnoDB存储引擎中,除了聚簇索引(Clustered Index),我们还可以使用二级索引(Secondary Index)来提高非主键列上的查询性能。二级索引是一种基于非主键列的B+树结构,用于快速定位数据记录。

(一)二级索引的特点

基于非主键列排序

二级索引的B+树结构基于指定的非主键列进行排序,这包括以下几个方面:

  • 页内记录排序:在每个页内,记录按照指定列(例如c2列)的大小顺序排成一个单向链表。
  • 页之间的排序:存放用户记录的页按照页内记录的指定列顺序排成一个双向链表。这种结构便于快速范围查询和顺序扫描。
  • 目录项页的排序:存放目录项记录的页根据页内目录项记录的指定列顺序排成一个双向链表,不同层次的页同样遵循这种排序规则。

叶子节点存储部分数据

与聚簇索引不同,二级索引的叶子节点存储的是索引列和主键列的值,而不是完整的用户记录。这种设计减少了存储空间的占用,但在查询过程中需要进行回表操作以获取完整的用户记录。

(二)二级索引的工作流程

假设我们创建了一个基于c2列的二级索引,并通过c2列的值查找某些记录,以查找c2列的值为4的记录为例,查找过程如下::

  1. 确定目录项记录页

    从根页面开始,根据c2列的值4定位到目录项记录所在的页,通过页44快速定位到目录项记录所在的页为页42(因为2 < 4 < 9)。

  2. 通过目录项记录页确定用户记录真实所在的页

    在页42中,根据c2列的值确定实际存储用户记录的页。由于c2列没有唯一性约束,值为4的记录可能分布在多个数据页中。最终确定实际存储用户记录的页在页34和页35中(因为2 < 4 ≤ 4)。

  3. 在真实存储用户记录的页中定位到具体的记录

    在页34和页35中定位到具体的记录,但二级索引的叶子节点中仅存储c2列和主键列c1的值。

  4. 回表操作

    根据主键值到聚簇索引中查找完整的用户记录。这个过程称为回表操作,即从二级索引定位到主键,再通过主键在聚簇索引中查找完整记录。

(三)二级索引的优缺点

二级索引的优点二级索引的缺点
提高查询效率:基于非主键列的查询可以利用二级索引快速定位数据,减少全表扫描的开销。回表操作:查询完整记录时需要回表操作,增加了一次I/O开销。
灵活性:可以为多个列创建二级索引,提升多种查询条件下的性能。占用空间:虽然叶子节点不存储完整记录,但仍会占用额外的存储空间。

二级索引通过基于非主键列排序和存储索引列与主键列的值,为非主键列的查询提供了高效的解决方案。然而,由于叶子节点仅存储部分数据,查询完整记录时需要回表操作。因此,合理使用和配置二级索引,对于提升数据库查询性能至关重要。 具体优化可见:MySQL索引性能优化分析。

四、联合索引

在InnoDB存储引擎中,联合索引(Composite Index)是一种基于多个列的索引,用于提高复杂查询的效率。联合索引通过对多个列进行排序,能够更有效地处理包含多个条件的查询。

同时以多个列的大小作为排序规则,也就是同时为多个列建立索引,比方说我们想让B+树按照c2c3列的大小进行排序,这个包含两层含义:

  • 先把各个记录和页按照c2列进行排序。
  • 在记录的c2列相同的情况下,采用c3列进行排序

c2c3列建立的索引的示意图如下:

如图所示,我们需要注意一下几点:

  • 每条目录项记录都由c2c3页号这三个部分组成,各条记录先按照c2列的值进行排序,如果记录的c2列相同,则按照c3列的值进行排序。

  • B+树叶子节点处的用户记录由c2c3和主键c1列组成。

(一)联合索引的特点

多列排序规则

联合索引按照多个列的值进行排序,其排序规则包括以下两个层次:

  • 第一列排序:首先按照第一个指定列(例如c2列)的值进行排序。
  • 第二列排序:在第一列相同的情况下,按照第二个指定列(例如c3列)的值进行排序。

在这个结构中,每个目录项记录由c2、c3和页号组成,叶子节点存储c2、c3和主键c1。

联合索引的组成

  • 目录项记录:每条目录项记录由c2、c3和页号组成,先按照c2列排序,如果c2列相同,则按照c3列排序。
  • 叶子节点记录:叶子节点处的用户记录包含c2、c3和主键c1列。这种结构使得查询包含c2和c3列的条件时更加高效。

(二)联合索引与单列索引的区别

联合索引

  • 建立联合索引会生成一棵B+树,该树按照c2和c3列进行排序。
  • 查询时,如果使用c2和c3作为条件,能够快速定位记录,减少查询时间。

单列索引

  • 为c2和c3分别建立索引会生成两棵独立的B+树,每棵树分别按照c2或c3进行排序。
  • 查询时,如果只使用c2或c3作为条件,可以利用相应的索引。但如果同时使用c2和c3作为条件,可能需要进行多次索引查找和合并操作,增加查询开销。

(三)联合索引的优缺点

联合索引的优点联合索引的缺点
高效的多列查询:联合索引能够显著提高包含多个列条件的查询性能。插入和维护成本较高:由于需要对多个列进行排序和维护,插入和更新操作可能较慢。
减少单列索引的数量:通过一个联合索引代替多个单列索引,可以节省存储空间。部分匹配限制:联合索引在查询中只能高效利用前缀列,如果查询条件不包括索引的最左列,索引的利用率会降低。

(四)联合索引的使用建议

前缀匹配原则

联合索引在查询中按照列的顺序生效,因此查询条件应尽量包括索引的最左列(即前缀列)。例如,创建了(c2, c3)的联合索引后,查询条件包含c2或(c2, c3)时能够有效利用索引。

适用场景

联合索引适用于需要同时基于多个列进行查询的场景。例如,在电商系统中,可以为商品类别和价格区间创建联合索引,以优化相关查询。

联合索引是InnoDB中一种重要的索引类型,通过对多个列进行排序和索引,提高了多列查询的性能。与单列索引相比,联合索引在处理复杂查询时更加高效。然而,合理的索引设计和使用对于优化数据库性能至关重要。理解联合索引的工作原理和最佳实践,可以帮助我们更好地利用MySQL数据库。  具体优化可见:MySQL索引性能优化分析。

五、总结

InnoDB中的索引是提高数据检索效率的关键。本文介绍了三种主要索引类型:

  1. 聚簇索引:基于主键排序存储完整的用户记录,适合快速主键查询和范围查询。
  2. 二级索引:基于非主键列排序,提升非主键查询性能,但需要回表操作。
  3. 联合索引:基于多个列排序,适用于复杂查询,能够显著提升多列条件查询的效率。

通过合理使用和配置这些索引,能有效提升数据库查询和数据操作的性能。理解索引的工作机制和最佳实践,对于优化MySQL数据库性能至关重要。

 参考文献、书籍及链接

  • 《MySQL技术内幕:InnoDB存储引擎》(第2版):MySQL技术内幕 (豆瓣)
  • 《MySQL 是怎样运行的:从根儿上理解 MySQL》
  • 《Inside InnoDB: The InnoDB Storage Engine》:MySQL :: MySQL 8.0 Reference Manual :: 15 The InnoDB Storage Engine
  • 《InnoDB: The Ultimate Guide》:https://www.percona.com/blog/2018/06/05/innodb-the-ultimate-guide/
  • 《InnoDB Storage Engine Internals》:https://mariadb.com/kb/en/innodb-storage-engine-internals/
  • InnoDB的数据页结构
  • InnoDB存储引擎B+树的树高推导_b+树一般多少层-CSDN博客
  • MySQL索引性能优化分析_mysql索引和性能分析(实战)-CSDN博客

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

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

相关文章

[数据结构与算法·C++] 笔记 1.5 流

流 标准输入输出流 标准输入流 cin>>x 读入整型数时以第一个非数字为终结读入字符串时以第一个空格、tab 或换行符为终结 其它方法 标准输出流 cout<<y cout 输出到标准设备cerr 输出错误信息clog 输出错误日志 输出不同进制 hex -> 16 进制dec -> 10 …

windows cuda12.1 pytorch gpu环境配置

安装cuda12.1 nvcc -V conda创建pythong3.10环境 conda create -n llama3_env python3.10 conda activate llama3_env 安装pytorch conda install pytorch torchvision torchaudio pytorch-cuda11.8 -c pytorch -c nvidia gpu - Pytorch version for cuda 12.2 - Stack Ov…

Stable Diffusion WebUI Forge 支持 Flux 了!

大家好&#xff0c;我是每天分享AI应用的萤火君&#xff01; Flux横空出世有段时间了&#xff0c;模型效果也得到了广泛的认可&#xff0c;但是 Stable Diffusion WebUI 官方迟迟没有跟进&#xff0c;据说是因为要修改很多底层的处理机制&#xff0c;加之ComfyUI如火如荼&…

鸿蒙OpenHarmony【轻量系统内核扩展组件(CPU占用率)】子系统开发

基本概念 CPU&#xff08;中央处理器&#xff0c;Central Processing Unit&#xff09;占用率分为系统CPU占用率和任务CPU占用率。 系统CPU占用率&#xff1a;是指周期时间内系统的CPU占用率&#xff0c;用于表示系统一段时间内的闲忙程度&#xff0c;也表示CPU的负载情况。系…

iOS 中 KVC 与 KVO 底层原理

KVC 本质&#xff1a; [object setValue: forKey:];即使没有在.h 文件中有property 的属性声明&#xff0c;setValue:forKey依然会按照上图流程执行代码 KVC 如果成功改变了成员变量&#xff0c;是一定可以被 KVO 监听到成员变量的前后改变的 KVO runtime会生成中间类&…

EmguCV学习笔记 C# 12.3 OCR

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访问…

ActiveMQ 的消息持久化策略

ActiveMQ 的消息持久化策略 消息持久化对于可靠消息传递来说是一种比较好的方法&#xff0c;即使发送者和接受者不是同时在线&#xff0c;或者消息中心在发送者发送消息后宕机了&#xff0c;消息中心重启后仍然可以将消息发送出去。 消息持久性的原理很简单&#xff0c;就是在发…

[Linux] 通透讲解 什么是进程

标题&#xff1a;[Linux] 通透讲解 什么是进程 个人主页&#xff1a;水墨不写bug &#xff08;图片来自网络&#xff09; 目录 一.深入进程基本概念 二.管理好进程 1.管理好进程的方法 2.描述进程-PCB 3.组织进程 正文开始&#xff1a; 本文按照对进程的先描述再组织进行…

C++之模版的进阶

1.非类型模版参数 模版参数分类类型与非类型形形参 类型形参&#xff1a;出现在模版参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。 非类型形参&#xff1a;用一个常亮作为类&#xff08;函数&#xff09;模版的一个参数&#xff0c;在类&#xff08;函数…

股指期货交割方式是什么?

说起股指期货&#xff0c;这可是个高大上的金融玩意儿。咱们平时买卖股票&#xff0c;那是看准了哪只股就下手&#xff0c;赚了就卖&#xff0c;赔了就扛&#xff0c;挺直接的。但股指期货呢&#xff0c;它玩的是未来的预期&#xff0c;就像是你跟人打赌明天天气好不好&#xf…

Fyne ( go跨平台GUI )中文文档-Fyne总览(二)

本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法 go代码展示为Go 1.16 及更高版本, ide为goland2021.2​​​​​​​ 这是一个系列文章&#xff1a; Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne…

《python语言程序设计》2018版第8章18题几何circle2D类(中部)

第一、重新分析 第一-1、我设计的第一模式第一-1-1、遇到的逻辑分析迷雾第一-1-2、无畏挣扎后的无奈 第二-1、我就把你们两个放到一起,第二-2、我的想法 当我看到了这个2个园并且比对. 第一-1、我设计的第一模式 设计一个最抽象的Circle2D类. 这个类只包含一个x,y和circle 这个…

Parallels Desktop 20 for Mac 推出:完美兼容 macOS Sequoia 与 Win11 24H2

Parallels Desktop 20 for Mac 近日正式发布&#xff0c;这一新版本不仅全面支持 macOS Sequoia 和 Windows 11 24H2&#xff0c;还在企业版中引入了一个全新的管理门户。新版本针对 Windows、macOS 和 Linux 虚拟机进行了多项改进&#xff0c;其中最引人注目的当属 Parallels …

让模型评估模型:构建双代理RAG评估系统的步骤解析

在当前大语言模型(LLM)应用开发的背景下,一个关键问题是如何评估模型输出的准确性。我们需要确定哪些评估指标能够有效衡量提示(prompt)的效果,以及在多大程度上需要对提示进行优化。 为解决这一问题,我们将介绍一个基于双代理的RAG(检索增强生成)评估系统。该系统使用生成代理…

免费开源的AI 智能网盘,图片和媒体管理工具 | 极空间部署『PicHome』

免费开源的AI 智能网盘&#xff0c;图片和媒体管理工具 | 极空间部署『PicHome』 哈喽小伙伴们好&#xff0c;我是Stark-C~ 想必很多小伙伴儿手机&#xff0c;电脑&#xff0c;甚至是网盘上都存取了大量的各类图片&#xff0c;不知道大家都是怎么管理你手头大量的图片的&…

食探秘:Spring Boot校园周边美食发现平台

第三章 系统设计 3.1 系统概要设计 本校园周边美食探索及分享平台选择B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式。适合在互联网上进行操作&#xff0c;只要用户能连网&#xff0c;任何时间、任何地点都可以进行系统的操作使用。系统工作原理图如图3-1所…

PMP--二模--解题--71-80

文章目录 13.干系人管理--干系人登记册--记录干系人的身份信息、评估信息、干系人分类。识别完干系人更新干系人登记册。71、 [单选] 一名初级项目经理被指派到一个新启动的项目&#xff0c;高级项目经理指示该初级项目经理去识别在项目中享有既得利益的人员。高级项目经理让初…

上半年营收净利双降,债台高筑下扩产能,天合光能“激进”前行?

近年来&#xff0c;随着新能源产业的蓬勃兴起&#xff0c;以及消费端对低碳经济追求的日益增强&#xff0c;再叠加分布式光伏发电系统的快速发展&#xff0c;全球市场对光伏组件的需求量愈发高涨。 而我国目前又是全球最大的光伏组件生产国和出口国&#xff0c;这离不开隆基绿…

桶排序和计数排序(非比较排序算法)

桶排序 桶排序是一种基于分配的排序算法&#xff0c;特别适合用来排序均匀分布的数据。它的基本思想是将输入的数据分到有限数量的桶里&#xff0c;然后对每个桶内的数据分别进行排序&#xff0c;最后再将各个桶内的数据合并得到最终的排序结果。(通常用于浮点数&#xff0c;因…

LLM大模型训练/推理的显卡内存需求计算

无论你是从头开始训练 LLM、对其进行微调还是部署现有模型&#xff0c;选择合适的 GPU 对成本和效率都至关重要。在这篇博客中&#xff0c;我们将详细介绍使用单个和多个 GPU 以及不同的优化器和批处理大小进行 LLM 训练和推理时 GPU 要求的所有信息。 计算机处理器由多个决定…