MySQL覆盖索引和索引跳跃扫描

最近在深入学习MySQL,在学习最左匹配原则的时候,遇到了一个有意思的事情。请听我细细道来。

我的MySQL版本为8.0.32

可以通过  show variables like 'version';  查看使用的版本。

准备工作:

先建表,SQL语句如下:

create table joint_index_test(id int primary key,a int,b int,c int
);
alter table joint_index_test add index index_a_b_c(a,b,c);

表结构非常简单,4个字段,两个索引,主键索引id和联合索引abc。暂时不向表中添加数据。

开始测试

接下来我们进行查询操作和使用explain查看select语句的执行

1. 最左匹配原则

1.explain select * from joint_index_test where a = 3;

这条SQL语句是否走了索引大家基本上都能够分析出来,基础比较好的小伙伴甚至可以直接分析出来扫描类型是什么。执行结果如下图:

由于where后面的条件是a,遵循联合索引的最左匹配原则,会使用索引index_a_b_c,进行查询。由于我们查询的列是*,在joint_index_test可以扩展为id,a,b,c,这些列在联合索引a,b,c中都可以查询到。所以MySQL在执行的时候,会选择使用覆盖索引,不再进行回表查询。【extra列为Using index】

继续进行测试第二条SQL语句

2. 覆盖索引

2.explain select * from joint_index_test where b = 3;

根据最左匹配原则,我们可以判断出来,第二条SQL语句应该不会使用到index_a_b_c联合索引,因为联合索引是按照字段的顺序从左到右进行构建的,也就是从字段a进行从小到大的排序,只有字段a相等的时候才会使用b,c进行排序。也就是说,b、c在全局是无序的,在局部却是有序的。当我们的条件中缺失联合索引最左边的字段时,MySQL在进行查询的时候,一般情况下,是不能够使用到联合索引了。

但是也有例外,像上面的这一条SQL语句,执行的时候会利用联合索引进行全索引扫描,因为我们要查询的字段在联合索引中都可以查询到,然后将所有查询到的结果使用where条件进行筛选。

为什么会优先走联合索引?

因为二级索引树的记录东西很少,就只有「索引列+主键值」,而聚簇索引记录的东西会更多,比如聚簇索引中的叶子节点则记录了主键值、事务 id、用于事务和 MVCC 的回滚指针以及所有的剩余列。MySQL的查询是基于成本的,会优先原则成本低的查询方案。

如果我们向joint_index_test表中添加一个name字段,这时候,我们要查询的所有字段就没有办法在联合索引中全部找到了,MySQL会放弃联合索引,改走全表扫描。

全索引扫描
添加一个name字段后,type从index->ALL

3. 索引跳跃扫描 

 我们将name字段删除,表中还只保留 id、a、b、c 四个字段,并向表中生成数据。

我们向表中生成一千条数据,id自增,a对1到6进行枚举,b、c是int类型的随机数。

我们再次执行   explain select * from joint_index_test where b = 3;这条SQL语句,发现type列和Extra列中的内容发生了变更。type从index  ->  range ; Extra列从Using Index  ->  Using index for skip scan.

之所以发生了这样的变化,是MySQL8.0.13后对最左原则失效的情况进行了优化。如果我们的联合索引构建的B+Tree中能够找到所有查询的列且where查询条件没有遵循最左匹配原则,MySQL会通过索引跳跃扫描进行优化处理。提前说明,索引跳跃扫描并不是万能的,我们在进行SQL查询的时候还是需要尽可能地遵循最左匹配原则。

接下来,我会根据MySQL官方文档对索引跳跃扫描进行解说,感兴趣的小伙伴也可以直接点击文末链接,自行阅读。

在MySQL8.0.13版本之前,执行这一条SQL语句,会出现 Using where,Using Index 使用索引扫描所有的数据,之后再利用条件进行过滤,其执行type为index对全索引进行扫描,性能仅次于ALL;

从MySQL 8.0.13版本开始,mysql支持多范围扫描;查询的条件的每个不同前缀值执行子范围扫描。例如会对 select * from joint_index_test where b = 3 这条SQL语句通过 distinct a 拆分成六条SQL语句,分别为:

  • explain select * from joint_index_test where a = 1 and b = 3;
  • explain select * from joint_index_test where a = 2 and b = 3;
  • explain select * from joint_index_test where a = 3 and b = 3;
  • explain select * from joint_index_test where a = 4 and b = 3;
  • explain select * from joint_index_test where a = 5 and b = 3;
  • explain select * from joint_index_test where a = 6 and b = 3;

让拆分后的语句能够遵循联合索引的最左匹配原则进行范围查询,之后对所有查询到的值进行合并,并作为整体返回。值得一提的是,索引跳跃扫描,并非跳过索引,而是在缺失的前缀索引的不同值之间进行跳跃;使用这种策略减少了访问的行数,因为MySQL直接跳过不符合的构造范围的行。还是那一句话,联合索引不是万能的,之中优化是基于以下条件的:

  1. 只适用于单表查询;
  2. 查询语句中不能使用GROUP BY或DISTINCT;
  3. 只能对联合索引中构建的B+数包含的列进行查询;
  4. 缺少的前缀必须是常数,数字类型的字段
  5. 查询条件必须适用连词进行连接,比如使用AND或者OR

以上还有一些条件,笔者暂时还没有看懂,值得一提的是,在满足上面的所有条件的情况下,索引跳跃扫描并不是一定发生的,因为对缺失的前缀进行组合是需要成本的。mysql的查询永远会选择成本最低的方案,而索引跳跃扫描仅仅是其中的一种方案。我们可以将索引跳跃扫描看作是覆盖索引条件查询缺失前缀的一种优化方案。

官方链接:MySQL :: MySQL 8.0 Reference Manual :: 10.2.1.2 Range Optimization

欢迎纠正与交流

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

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

相关文章

golang基础用法

一、基础用法 基础定义 // 变量 var int i i 5 i :5 i, j : 3,"dsafd"// 常量const ( i "adfa" b 5 )// 特殊常量itoa itoa重新出现表示规0 后面会自动1 const (Monday iota // 0Tuesday // 1Wednesday // 2Thursday // 3Friday…

Element Plus 与 Vue 3:构建现代化 Web 应用的完美搭档

引言 Element Plus是基于Vue 3的组件库,它继承了Element UI的优秀基因,为Vue 3应用提供了丰富的界面组件。Element Plus不仅拥有与Element UI相同的高质量组件,还针对Vue 3进行了优化和更新,确保了与Vue 3的无缝集成。 环境准备…

Vue3单文件jsx输出多组件示例遇到的坑

感谢博主减肥吧Evan提供的SFC实现多组件的思路和实现&#xff0c;小卷在大佬的基础上再完善下实现。 我们从tsx的API使用上得到启发&#xff0c;可以在vue的单文件组件&#xff08;sfc&#xff09;中使用defineComponent来定义和导出多个独立的小组件。此时sfc中的<templat…

SSM框架学习笔记(仅供参考)

&#xff08;当前笔记简陋&#xff0c;仅供参考&#xff09; 第一节课&#xff1a; &#xff08;1&#xff09;讲述了Spring框架&#xff0c;常用jar包&#xff0c;以及框架中各个文件的作用 &#xff08;2&#xff09;演示了一个入门程序 &#xff08;3&#xff09;解释了…

Redis 实现的延时队列组件

最近看开源看到一个好用的延时队列组件&#xff0c;已经上生产。代码量很少&#xff0c;主要就是利用Redis监听过期键实现的。然后搞点策略模式柔和柔和。利用Spring Start 封装了一下&#xff0c;全是俺掌握的知识&#xff0c;稍微研究了下就搞懂了。觉得挺有用的&#xff0c;…

006-三台交换机堆叠

三台交换机堆叠 链形连接和环形连接 链形配置IRF与环形配置IRF的区别 三个交换机链形配置IRF与三个交换机环形配置IRF的主要区别体现在以下几个方面&#xff1a; 物理位置要求&#xff1a; 链形连接&#xff1a;对成员设备的物理位置要求相对较低&#xff0c;主要适用于成员…

计算机课程名,汇总

MP-ZHI, CS-DOG, R, NBA ! 助记词&#xff1a;媒婆知道&#xff0c;CS-DOG&#xff0c;认识NBA明星&#xff01; M&#xff0c;密&#xff0c;《网络安全》P&#xff0c;Performance&#xff0c;性能卓越的&#xff0c;指的是超算Z&#xff0c;组&#xff0c;《计算机组成原理…

Linux下如何解压rar文件

在windows下我们压缩解压文件通常后缀为rar&#xff0c;在linux下我们压缩解压文件通常后缀为tar 默认在linux下我们不能解压压缩rar文件&#xff0c;那我们如何使用呢&#xff1f; 我们可以下载rarlinux安装包实现解压压缩后缀为rar的包 下载地址&#xff1a;https://www.r…

HybridCLR + Addressable 热更新篇(一)

目录 前言一、HybridCLR 和 Addressable 是什么&#xff1f;1. HybridCLR2. Addressable 二、使用步骤1.HybridCLR导入2.HybridCLR配置3.Addressable导入4.Addressable配置 前言 随着移动互联网和游戏行业的快速发展&#xff0c;热更新技术变得越来越重要。热更新能够在不重新…

图——定义和基本术语

图是数据结构中非常重要的一章&#xff0c;这篇文章就先介绍一下图的定义和基本术语。 一&#xff0c;图的构成 图&#xff1a;Graph(V,E) V&#xff1a;顶点(数据元素)的有穷非空集合&#xff1b; E&#xff1a;边的有穷集合。 如下面这个图&#xff0c;由点集和边集可以确定…

Python的分布式系统设计与开发

Python中的分布式系统设计与开发是一个复杂而广泛的主题&#xff0c;它涉及多个方面&#xff0c;包括系统架构、组件设计、通信机制、数据处理等。以下是对Python中分布式系统设计与开发的详细说明&#xff1a; 一、分布式系统基础 1. 定义与特点 分布式系统是指由多个独立的…

C++——类与对象(下)

在类与对象的上和中已经把类与对象的大部分内容讲了&#xff0c;这里对最后的一些内容进行补充说明。 目录 一、初始化列表 二、类型转换 三、static成员 四、友元 五、内部类 六、匿名对象 一、初始化列表 之前我们在实现构造函数的时候&#xff0c;初始化成员变量主要是使用…

mupdf 编译说明

进入官网下载源码&#xff1a;https://www.mupdf.com/releases 挑选需要的版本&#xff0c;下载解压&#xff0c;然后打开解决方案&#xff0c;进行编译

python 怎样生成窗体

通过import tkinter导入Tkinter模块&#xff0c;没有这句下面的都不成立了。 wintkinter.Tk()&#xff0c;这句是创建windows的窗口对象&#xff0c;注意后面的Tk&#xff0c;大小写。 win.title("窗口")&#xff0c;这段是设置窗口上的标题。 另外窗口的大小你可以通…

Linux操作系统特殊权限、文件系统管理命令、网络配置命令

Linux操作系统特殊权限 在Linux操作系统中&#xff0c;除了常规的读、写、执行权限外&#xff0c;还有一些特殊权限用于控制文件和目录的访问行为。这些特殊权限包括SUID&#xff08;Set User ID&#xff09;、SGID&#xff08;Set Group ID&#xff09;和Sticky Bit&#xff…

LlamaIndex 结构化输出

我们和大模型是通过 prompt 进行交互的&#xff0c;我们提示什么&#xff0c;大模型就输出什么。 假如我们要求大模型输出结构化的数据如 JSON&#xff0c;yaml 是不是也可以&#xff1f; 第一个例子 先建一个索引&#xff1a; from llama_index.core import VectorStoreIn…

java实战项目-学生管理系统(附带全套源代码)--《基础篇》

一、前言 第一个java小型学生管理系统&#xff0c;思路和其他语言都一样&#xff0c;因为有C语言的基础&#xff0c;写这个并不是太难&#xff0c;不过&#xff0c;进阶篇的就难太多了。明天晚上更新进阶篇&#xff0c;因为目前代码还没有完善&#xff0c;保守估计需要500行代…

网络请求优化:如何让你的API飞起来

网络请求优化&#xff1a;如何让你的API飞起来 亲爱的开发者朋友们&#xff0c;你是否曾经遇到过这样的场景:用户疯狂点击刷新按钮,你的服务器却像老年人散步一样慢吞吞地响应。或者,你的应用像个贪吃蛇,疯狂吞噬用户的流量包。如果你对这些情况再熟悉不过,那么恭喜你,你正需要…

Unity ColorSpace 之 【颜色空间】相关说明,以及【Linear】颜色校正 【Gamma】的简单整理

Unity ColorSpace 之 【颜色空间】相关说明&#xff0c;以及【Linear】颜色校正 【Gamma】的简单整理 目录 Unity ColorSpace 之 【颜色空间】相关说明&#xff0c;以及【Linear】颜色校正 【Gamma】的简单整理 一、简单介绍 二、在Unity中设置颜色空间 三、Unity中的Gamma…

部队物资仓库出入库管理系统|实现物资有效的战备保障

随着科技的不断发展&#xff0c;智慧营区已成为现代军事管理的重要方向。后勤物资管控作为营区管理的重要组成部分&#xff0c;对于保障营区正常运转和提高部队战斗力具有重要意义。智慧营区后勤物资管控平台作为数字化后勤建设的重要组成部分&#xff0c;能够实现营区物资的智…