MySQL 联合索引底层存储结构及索引查找过程解读

前言

  • 大家好,我是 Lorin ,联合索引(Composite Index)又称复合索引,它包括两个或更多列。与单列索引不同,联合索引可以覆盖多个列,这有助于加速复杂查询和过滤条件的检索。联合索引的列顺序非常重要,因为查询优化器会按照索引列的顺序执行搜索。
  • 本文将从联合索引基本概念、底层存储结构、索引查找过程、实践建议几个方面图文并茂进行详细介绍。

版本

代码语言:sql

复制

SELECT VERSION();5.7.36-log

数据准备

SQL

代码语言:sql

复制

// 创建表
CREATE TABLE `test_table_union_index` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`merchant_id` int(20) NOT NULL,`order_id` int(20) NOT NULL,PRIMARY KEY (`id`),KEY `merchant_id_order_id_union_index` (`merchant_id`,`order_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4;// 插入数据
INSERT INTO `test_table_union_index` (`merchant_id`, `order_id`) VALUES (3, 1);
INSERT INTO `test_table_union_index` (`merchant_id`, `order_id`) VALUES (3, 2);
INSERT INTO `test_table_union_index` (`merchant_id`, `order_id`) VALUES (4, 3);
INSERT INTO `test_table_union_index` (`merchant_id`, `order_id`) VALUES (4, 3);
INSERT INTO `test_table_union_index` (`merchant_id`, `order_id`) VALUES (5, 1);
INSERT INTO `test_table_union_index` (`merchant_id`, `order_id`) VALUES (5, 2);// 查询 SQL EXPLAIN 分析
EXPLAIN SELECT * FROM test_table_union_index WHERE merchant_id = 3 AND order_id = 2;

数据创建结果

  • SQL 执行完成后,我们可以看到数据库存储了如下数据:

SQL执行后生成的数据

SQL执行后生成的数据

有无联合索引执行情况

代码语言:sql

复制

// 查询 SQL EXPLAIN 分析
EXPLAIN SELECT * FROM test_table_union_index WHERE merchant_id = 3 AND order_id = 2;
无联合索引

无联合索引分析

无联合索引分析

存在联合索引

创建联合索引后分析

创建联合索引后分析

底层存储结构

底层存储结构

底层存储结构

  • 上图是联合索引 “merchant_id_order_id_union_index” 的底层存储结构(不一定和 MySQL 数据库底层实现完全一致),我们可以看到除了具有单列索引的特点外,联合索引还具有以下一些特点:

代码语言:sql

复制

- B+树通过索引首列值构建,如 merchant_id_order_id_union_index 根据 merchant_id 构建。
- 叶子节点拥有联合索引中的所有字段以及主键字段,且叶子节点数据局部有序,如我们有一个三个字段的联合索引(a,b,c):
叶子节点(1):
a,b,c(1,3,3)
a,b,c(1,3,4)
a,b,c(1,4,1)
a,b,c(1,4,2)叶子节点(2)
a,b,c(2,3,3)
a,b,c(2,3,4)
a,b,c(2,4,1)
a,b,c(2,4,2)a 列在B+树整体有序,a 列相同的情况下 b 列数据按序排列,但 c列不一定有序。

查询过程

最左匹配原则

  • 联合索引遵循最左匹配原则,只能从左往右依次搜索联合索引字段,否则索引字段不生效。

代码语言:txt

复制

例如索引是 key_index (a,b,c)。 可以支持 a 、a,b 、a,b,c 3种组合进行查找,但不支持 b,c 、c 进行查找。

查询过程解析

联合索引数据查询过程

联合索引数据查询过程

代码语言:sql

复制

SELECT * FROM test_table_union_index WHERE merchant_id = 3 AND order_id = 2;
  • 联合索引遵循最左匹配原则,以上述查询 SQL 为例,联合索引先根据 merchant_id = 3 在构建的B+树索引上进行查询数据,找到叶子节点:

叶子节点 3

叶子节点 3

  • 然后根据 order_id = 2 查询定位数据,查询到数据对应的主键 ID = 2,最后进行回表查询。

联合索引优势

支持复杂查询

  • 联合索引能够加速包含多个条件和多个列的查询。这对于联接多个表或需要在多列上进行过滤的查询非常有用。

索引覆盖查询

  • 联合索引可以覆盖多个查询中的列,从而减少了数据库的I/O负载。这意味着数据库不必访问数据行,而可以直接使用索引来满足查询条件。

提高排序和分组性能

  • 如果你的查询需要排序或分组结果,联合索引可以在这方面提供显著的性能改进,特别是当排序或分组涉及索引中的列时。

减少索引数量

  • 使用联合索引可以减少索引的数量,这对于大型数据库来说是一个重要考虑因素,因为每个额外的索引都会增加数据库维护的开销。

使用建议

联合索引的列顺序十分重要

  • 确定哪些列应包括在联合索引中,以及它们的顺序非常重要。通常将最频繁用于过滤条件的列放在索引前面。

建议能使用联合索引尽量使用联合索引

  • 应该尽可能使用联合索引,但联合索引无法满足需求时可以结合单列索引使用。

常见问题分析

为什么遵循最左匹配原则

  • 从联合索引的底层存储结构我们可以知道,联合索引是根据字段从左往右组织的,不从左边的字段开始查询无法使用索引。

联合索引中字段范围查询为什么会导致后续联合索引字段可不用

  • 从联合索引的底层存储结构我们可以知道,叶子节点数据局部有序,下面的案例可以清楚饿展示这个问题:

代码语言:txt

复制

假设存在如下数据:
1(b=1,c=4,d = 10)
2(b=2,c=5,d = 6)
3(b=2,c=5,d = 7)
4(b=3,c=1,d = 2)
5(b=3,c=5,d = 1)查询条件: b > 1 且 c = 5 , d = 6先查找 b > 1 :
2(b=2,c=5,d = 6)
3(b=2,c=5,d = 7)
4(b=3,c=1,d = 2)
5(b=3,c=5,d = 1)再查找 c = 5 , 此时 c 并不是有序的,因此无法使用联合索引字段 c,而是需要遍历所有4条数据(如果是有序:1,2,3,4,5,6,7,8 查找到5后就不再扫描):
2(b=2,c=5,d = 6)
3(b=2,c=5,d = 7)
5(b=3,c=5,d = 1)综上所述:联合查询中范围查询会导致后续字段数据无序,导致联合索引中后续索引字段失效。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从零开始学cv-17:图像绘制基本图形

文章目录 前言一、绘制直线与箭头二、绘制矩形三、绘制圆形椭圆形 前言 随着计算机视觉技术的不断发展,OpenCV作为一款强大的开源图像处理库,受到了越来越多开发者的喜爱。本文将带领读者走进OpenCV的世界,从基础入手,详细介绍如…

冷热数据分离

优质博文:IT-BLOG-CN 一、背景 随着机票业务的快速发展,订单量持续增长对业务性能带来影响,需要进行冷热数据分离。目前机票订单模块主要使用Mysql(InnoDB)作为数据库存储,历史订单信息状态修改频率低并占用大量数据库存储空间&…

腾讯IM SDK:TUIKit发送多张图片

一、问题描述 在使用腾讯IM DEMO&#xff08;https://github.com/TencentCloud/chat-uikit-vue.git&#xff09;时发现其只支持发送一张图片&#xff1a; 二、解决方案 // src\TUIKit\components\TUIChat\message-input-toolbar\image-upload\index.vue<inputref"inp…

AcWing 802. 区间和(离散化算法,python)

本篇博客详细讲解一下离散化知识点&#xff0c;通过讲解和详细列题带大家掌握离散化。 题目&#xff1a; 原题链接&#xff1a;https://www.acwing.com/problem/content/description/804/ 假定有一个无限长的数轴&#xff0c;数轴上每个坐标上的数都是 0。 现在&#xff0c;…

记一次pyc逆向

.py文件   源代码文件。   这是开发者编写的 Python 源代码文件&#xff0c;包含了可执行的 Python 代码。 .pyc文件   字节码文件。   Python 源文件&#xff08;.py&#xff09;在执行时会被编译为字节码&#xff0c;并存储在 __pycache__ 目录下&#xff0c;文件名通…

PHP变量(第④篇)

本栏目教学是php零基础到精通&#xff0c;如果你还没有安装php开发工具请查看下方链接&#xff1a; Vscode、小皮面板安装-CSDN博客 今天来讲一讲php中的变量&#xff0c;变量是用于存储信息的"容器"&#xff0c;这些数据可以在程序执行期间被修改&#xff08;即其…

解决Nginx出现“Too many open files”的问题

解决Nginx出现“Too many open files”的问题 在那个不经意的瞬间&#xff0c;我感到一阵莫名的恍惚。同事突然提出要看我的手机&#xff0c;她的目光落在了我那泛黄的手机壳上。出乎意料地&#xff0c;她开始细心地擦拭&#xff0c;从内到外&#xff0c;动作轻柔而专注。那一刻…

Linux——磁盘分区、挂载

Linux 分区 原理介绍 原理图如下 当我们在/home目录下新建一个文件a.txt时&#xff0c;该文件实际上是存放在硬盘B的分区1中的&#xff0c;这就是图里说的&#xff0c;当进入某个目录&#xff0c;可以进入到该目录下挂载的分区里的意思 硬盘说明 应用实例&#xff1a;挂载一个…

【Flask】Flask数据库

【Flask】Flask数据库 1.概述2.使用Flask-SQLAlchemy管理数据库3.定义模型4.关系5.数据库操作创建表插入行修改行删除行查询行 1.概述 大多数的数据库引擎都有对应的 Python 包&#xff0c;包括开源包和商业包。Flask 并不限制你使用何种类型的数据库包&#xff0c;因此可以根…

PhotoMaker部署文档

一、介绍 PhotoMaker&#xff1a;一种高效的、个性化的文本转图像生成方法&#xff0c;能通过堆叠 ID 嵌入自定义逼真的人类照片。相当于把一张人的照片特征提取出来&#xff0c;然后可以生成你想要的不同风格照片&#xff0c;如写真等等。 主要特点&#xff1a; 在几秒钟内…

前端登录页面验证码

首先&#xff0c;在el-form-item里有两个div&#xff0c;各占一半&#xff0c;左边填验证码&#xff0c;右边生成验证码 <el-form-item prop"code"><div style"display: flex " prop"code"><el-input placeholder"请输入验证…

小赢卡贷公益行:乡村振兴与多元公益并进

在金融科技的浪潮中&#xff0c;小赢卡贷不仅以其创新的金融产品和服务赢得了市场的广泛认可&#xff0c;更以其背后的公益之心&#xff0c;积极履行社会责任&#xff0c;传递着温暖与希望。小赢公益基金会&#xff0c;作为小赢卡贷社会责任的延伸&#xff0c;主要聚焦于乡村振…

Hi3061M开发板——系统时钟频率

这里写目录标题 前言MCU时钟介绍PLLCRG_ConfigPLL时钟配置另附完整系统时钟结构图 前言 Hi3061M使用过程中&#xff0c;AD和APT输出&#xff0c;都需要考虑到时钟频率&#xff0c;特别是APT&#xff0c;关系到PWM的输出频率。于是就研究了下相关的时钟。 MCU时钟介绍 MCU共有…

unix中如何申请进程调度的优先级

一、前言 unix系统中&#xff0c;进程的调度是由内核决定的。在一个系统中&#xff0c;进程的优先级越高&#xff0c;表示其在一定时间中占用cpu的时间越久。本文将介绍unix系统如何修改以及获取进程的优先级。 二、nice值 nice值是unix系统中用于表征进程优先级的一个参数。…

ssh -T git@github.com 出现异常

上传代码到github 私有仓库 步骤 1. 生成 SSH Key&#xff08;如果没有&#xff09; 打开终端并运行&#xff1a; bash 复制 ssh-keygen -t ed25519 -C "your_emailexample.com"按提示保存密钥文件和设置密码短语&#xff08;可选&#xff09;。默认位置是 ~/.…

recyclerView(kotlin)

recyclerView的优点 使用viewHolderRecycledViewPool的方式复用资源&#xff0c;提高性能利用LayoutManager&#xff0c;可根据不同需求使用不同的布局&#xff0c;且可以方便使用对应布局提供的方法&#xff0c;如快速定位item等。RecyclerView 提供了一个 ItemAnimator 接口…

计算机毕业设计Django+Vue.js豆瓣图书推荐系统 图书评论情感分析 豆瓣图书可视化大屏 豆瓣图书爬虫 数据分析 图书大数据 大数据毕业设计 机器学习

《DjangoVue.js豆瓣图书推荐系统》开题报告 一、研究背景与意义 1. 研究背景 随着数字化时代的来临&#xff0c;图书资源日益丰富&#xff0c;用户面临着信息过载的问题。如何在海量图书中快速找到符合个人兴趣和需求的书籍成为了亟待解决的问题。传统的图书检索方式往往基于…

OmniDrive 论文学习

OmniDrive: A Holistic LLM-Agent Framework for Autonomous Driving with 3D Perception, Reasoning and Planning 解决了什么问题&#xff1f;相关工作端到端自动驾驶多模态语言模型&#xff08;MLLMs&#xff09;Drive LLM-Agents and BenchmarksDrive LLM-Agents基准测试 提…

柔性作业车间调度(FJSP)

1.1 调度问题的研究背景 生产调度是指针对一项可分解的工作(如产品制造),在尽可能满足工艺路线、资源情况、交货期等约束条件的前提下,通过下达生产指令,安排其组成部分(操作)所使用的资源、加工时间及加工的先后顺序,以获得产品制造时间或成本最优化的一项工作。 一般研究车间…

MySQL 日志 - Binlog

文章目录 binlog 的格式mysqbinlog 工具SHOW binlog events;binlog 和 redo log 对比 https://dev.mysql.com/doc/refman/8.4/en/binary-log.html binlog 全称 BinaryLog&#xff0c;是 MySQL 数据库中用于记录所有更改数据库状态的事件的日志文件。它主要用于以下几个目的&am…