【MySQL】全面剖析索引失效、回表查询与索引下推

1.索引失效的情况

以tb_user表举例,id为主键索引、name和phone字段上建立了一个普通索引,name和phone均为varchar类型。

索引列运算

当在 WHERE 子句或 JOIN 子句中对列使用函数或表达式时,索引会失效。

执行以下语句,可以发现执行计划中索引已经生效。

explain select * from tb_user where name = 'Jack';

如果我们使用substring函数只取前三个字符,则索引失效。

explain select * from tb_user where SUBSTRING(name, 1, 3) = 'Jac';

可以发现type为ALL,key为null,说明本次查询没有执行索引,走的是全表扫描

隐式类型转换

当列的类型和查询中的值类型不同时,MySQL 可能会进行隐式类型转换,导致索引失效。

执行以下语句,phone为varchar类型,如果等号右侧不加引号,则发生隐式转换,索引失效。

explain select * from tb_user where phone = 13016161546;

前导通配符查询

使用通配符查询时,如果通配符在字符串的前面,索引会失效。

执行以下语句,查询name字段后缀为ack的数据,索引失效。

explain select * from tb_user where name like '%ack';

or连接条件

当 or 条件中某个列没有索引时,索引会失效

执行以下语句,因为name和phone都是索引字段,索引正常生效。

explain select * from tb_user where name = 'Jack' or phone = '15846234682';

执行以下语句,因为age字段没有设置索引,所以索引失效查询。

explain select * from tb_user where name = 'Jack' or age = '20';

最左匹配原则

对于联合索引(多个列组成的索引),如果查询条件不包含索引的最左前缀部分,索引会失效。

TIPS: 这里指的最左是联合索引中的顺序,而不是SQL语句查询条件的顺序。

在本例中,我们新建一个表table,给字段col1、col2、age建立联合索引(col1, col2, age)

  • 遵循最左匹配发展

按照最左前缀法则查询数据。

explain select * from `table` where col1 = 'user' and col2 = 'password' and age = 21;

可以发现,联合索引的总长度为107

  • 不遵循最左匹配法则(查询条件中不包括联合索引的最左前缀部分)

如果不按照最左匹配法则,直接查询col2的数据

explain select * from `table` where col2 = 'password';

本次查询走的是index全索引扫描,性能上要低于ref

  • 不遵循最左匹配法则(查询条件中包含> <范围查询)

如果查询条件中使用了> <,则不遵循最左匹配法则(可以使用其他范围查询符号),范围查询右侧的索引失效。

执行以下语句,由于age在联合索引(col1, col2, age)中是最后一个,所以不存在其右侧索引失效的情况。

explain select * from `table` where col1 = 'user' and col2 = 'password' and age > 21;

但是如果我们将col2和age调换顺序,改为(col1, age, col2),则col2索引失效。

数据分布情况

MySQL会根据表中数据的分布情况,决定是否使用索引

举一个简单的例子,如果表中的age字段最小值为10,查询条件为age >= 10。则在查询时可能不会走索引,因为走索引和不走索引都需要查询表中的全部数据,不过判断一个语句是否走索引还是要根据explain关键字返回的结果进行判断。

2.回表查询

回表查询是指在使用辅助索引(二级索引)进行查询时,由于辅助索引中不包含查询所需的所有列数据,数据库必须通过索引找到对应的数据行位置,再去实际的数据表(即“回表”)中读取完整的数据行。这种操作会增加额外的 I/O 开销,因此回表查询通常比直接从索引中获取数据的查询更慢。

回表查询示例

假设有以下表数据,id为主键索引,name为普通索引。

主键索引(id)的索引结构如下图,在叶子节点中存储的是每一行的数据。如果我们直接根据id查询,就可以在遍历索引时直接拿到每一行的数据。

select * from tb_user where id = 2;

辅助索引(name)的索引结构如下,叶子节点存储的是该行的主键(id),如果需要查询该行的数据,则需要遍历索引后获得主键id,再根据这个主键id前往主键索引中查询,这个过程就是回表查询

select * from tb_user where name = 'Arm';

避免回表查询

避免回表查询很简单,只需要保证查询的列能够被索引结构覆盖即可。通过创建一个包含所有查询所需列的索引,数据库可以直接从索引中获取所有需要的数据,无需回表。

覆盖索引(Covering Index)是指查询所需的所有列都包含在同一个索引中,从而避免回表操作。这样可以显著提高查询性能。

比如我们直接使用以下语句,就可以避免回表查询,因为name索引中包含了name和id的数据,而无需回到数据库进行查询。

select name from tb_user where name = 'Arm';select id, name from tb_user where name = 'Arm';

3.索引下推

索引下推(Index Condition Pushdown,ICP) 是 MySQL 5.6 及以上版本中引入的一种优化技术,用于提高使用索引查询的效率。ICP 可以减少回表操作(即从索引表跳回数据表读取完整行数据)的次数,从而提高查询性能。

除了可以减少回表次数之外,索引下推还可以减少存储引擎层和 Server 层的数据传输量。

工作原理

在没有索引下推的情况下,MySQL 的查询执行流程通常是:

  1. 索引扫描:存储引擎使用索引查找满足索引条件的记录。
  2. 返回记录:将这些记录返回给 MySQL 服务器。
  3. 行过滤:MySQL 服务器根据剩余的查询条件进一步过滤这些记录。

使用索引下推后,MySQL 优化器会在索引扫描阶段尽可能多地应用查询条件,只有在通过索引扫描无法完全过滤的情况下,才进行回表操作。

适用场景

索引下推在以下场景中尤其有效:

  1. 范围查询:对索引列进行范围查询时,例如 BETWEEN<> 等。
  2. 联合索引查询:在联合索引的前缀列上进行查询,并且查询条件涉及非索引列时。
  3. 复杂条件查询:查询条件包含多个过滤条件时,例如 ANDOR 等。

示例

假设有一个包含联合索引 idx_name_age 的表 tb_user

CREATE TABLE tb_user (id INT PRIMARY KEY,name VARCHAR(50),age INT,address VARCHAR(255),INDEX idx_name_age (name, age)
);

查询语句:

explain select * from tb_user where name = 'John' and age > 30 and address like '%Street%';

在没有索引下推的情况下,MySQL 会:

  1. 使用索引 idx_name_age 找到 name = 'John' 的所有记录。
  2. 回表读取每一条记录的实际数据。
  3. 对回表后的数据应用剩余条件 age > 30address LIKE '%Street%' 进行过滤。

在启用索引下推的情况下,MySQL 会:

  1. 使用索引 idx_name_age 找到 name = 'John'age > 30 的记录(在索引扫描阶段应用部分条件)。
  2. 仅对符合前两个条件的记录进行回表操作。
  3. 对回表后的数据应用剩余条件 address LIKE '%Street%' 进行最终过滤。

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

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

相关文章

STM32-门电路-储存器-寄存器-STM32f1-MCU-GPIO-总线-keil5-点led

1、门电路 门电路组成简单加法器&#xff1a; 二进制对电路的影响&#xff1a; 0和1代表无和有&#xff1b; 以下图例&#xff0c;演示与门&#xff1a;左1右1输出1&#xff1b; 电平标准&#xff1a;使用不同的电压表示数字0和1&#xff1b; 高电平&#xff1a;1&#xff1…

AI在医学领域:残差扩散模型预测特发性肺纤维化 (IPF)

关键词&#xff1a; IPF 进展预测、残差扩散模型、临床信息 特发性肺纤维化&#xff08;Idiopathic Pulmonary Fibrosis&#xff0c;IPF&#xff09;是一种严重且不可逆的肺部疾病&#xff0c;它会导致肺部组织出现瘢痕和增厚&#xff0c;从而引起呼吸困难。。及时对IPF进行治…

电子围栏报警系统的创新应用

在科技日新月异的今天&#xff0c;安全防护技术正以前所未有的速度发展&#xff0c;其中&#xff0c;电子围栏报警系统作为智能安防领域的佼佼者&#xff0c;正逐步成为各行各业守护安全的主要选择方案。这一创新技术的应用&#xff0c;不仅极大地提升了安全防护的效率和精准度…

24/8/7 算法笔记 支持向量机回归问题天猫双十一

import numpy as np from sklearn.svm import SVR import matplotlib.pyplot as plt X np.linspace(0,2*np.pi,50).reshape(-1,1) y np.sin(X) plt.scatter(X,y) 建模 线性核函数 svr SVR(kernel linear) svr.fit(X,y.ravel())#变成一维y_ svr.predict(X) plt.scatter(…

阿里云播放器 web端 问题解决总结

1&#xff1a;ios设备长按视频&#xff0c;会出现系统的放大镜效果&#xff1a; 可以只监听touchstart事件即可 var playerContainer document.getElementById(this.playerId); playerContainer.addEventListener(touchstart, preventZoom, { passive: false }); playerConta…

unity 创建项目报错feature has expired (H0041),sentinel key not found (H0007)

两个报错同一种处理方式。 1、删除以下路径所有文件&#xff1a;C:\ProgramData\SafeNet Sentinel&#xff08;注意&#xff1a;ProgramData为隐藏文件&#xff09; 2、打开Cmd&#xff08;WinR键&#xff0c;输入cmd回车&#xff09;&#xff0c;进入Unity安装所在盘符&#…

为啥https比http慢

Https有ssl的握手 HTTP没有 HTTPS TCP 和HTTP 的TCP 时间差不是很大 HTTPS请求中,ssl所占的时间比例是请求时间总和93.37%, HTTPS请求中,ssl的请求会是tcp请求的14倍,而HTTP中没有这个问题 建议:对安全要求不是很高的,不要使用https请求 图例

自定义DIY线上预约小程序源码系统 带完整的安装代码包以及搭建部署教程

系统概述 随着移动互联网的快速发展&#xff0c;人们越来越习惯于通过手机进行各种活动的预约。传统的预约方式往往存在着信息不透明、沟通不畅、效率低下等问题&#xff0c;无法满足用户日益增长的需求。同时&#xff0c;对于企业和商家来说&#xff0c;建立一个专属的线上预…

Isaac Lab 安装 (ubuntu22.04环境)

Windows下的安装见这篇博客&#xff1a; Isaac Lab 安装与初体验 &#xff08;windows环境&#xff09;-CSDN博客 ubuntu22.04下的安装与windows下十分类似&#xff0c;还是参考官方的&#xff0c;Installation using Isaac Sim Binaries Installation using Isaac Sim Bina…

Linux驱动开发—ioctl命令构成,设备驱动基础使用ioctl详解

文章目录 1.什么是ioctl?示例 2.ioctl 与 write&#xff0c;read 有什么区别&#xff1f;复杂的设备控制多种数据类型和操作简化应用层代码区分数据和控制 3.ioctl命令的构成宏定义的组成部分具体的宏定义举个栗子 4.ioctl命令的分解宏定义举个栗子 5.ioctl 设备使用应用程序构…

【游戏引擎之路】登神长阶(九)——《3D游戏编程大师技巧》:我想成为游戏之神!

5月20日-6月4日&#xff1a;攻克2D物理引擎。 6月4日-6月13日&#xff1a;攻克《3D数学基础》。 6月13日-6月20日&#xff1a;攻克《3D图形教程》。 6月21日-6月22日&#xff1a;攻克《Raycasting游戏教程》。 6月23日-7月1日&#xff1a;攻克《Windows游戏编程大师技巧》。 7月…

数据库篇--八股文学习第十六天| MySQL的执行引擎有哪些?;MySQL为什么使用B+树来作索引;说一下索引失效的场景?

1、MySQL的执行引擎有哪些&#xff1f; 答&#xff1a; MySQL的执行引擎主要负责查询的执行和数据的存储, 其执行引擎主要有MyISAM、InnoDB、Memery 等。 InnoDB引擎提供了对事务ACID的支持&#xff0c;还提供了行级锁和外键的约束&#xff0c;是目前MySQL的默认存储引擎&…

Codeforces Round 963 (Div. 2)

A题&#xff1a;Question Marks 题目&#xff1a; Tim正在做一个由 4n 个问题组成的测试&#xff0c;每个问题都有 4 个选项&#xff1a;“A”、“B”、“C”和“D”。对于每个选项&#xff0c;有 n 个正确答案对应于该选项&#xff0c;这意味着有 n 个问题的答案为“A”。 n…

个人知识库与RAG的技术

构建个人知识库时&#xff0c;采用RAG结合LangChain的方法极为有效。RAG&#xff0c;即检索增强生成技术&#xff0c;是一种前沿的自然语言处理手段&#xff0c;它融合了信息检索的精确匹配与语言模型的高效文本生成&#xff0c;为处理自然语言相关任务提供了一种既灵活又准确的…

未来已来:人工智能如何重塑Facebook的用户体验?

在数字化时代的浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;正成为推动技术进步和用户体验优化的核心力量。Facebook&#xff08;现Meta Platforms&#xff09;作为全球领先的社交媒体平台&#xff0c;正在充分利用人工智能技术&#xff0c;以重塑用户体验&#xff0…

Spring Boot 3.0 热部署

idea开发环境下的spring boot 3.0热部署启用非常简单&#xff0c;并没有网上教程讲的需要对idea做一些设置。 只需引入依赖&#xff1a; developmentOnly org.springframework.boot:spring-boot-devtools其他不需要做任何设置。 服务启动中&#xff0c;改了代码或配置后&…

振动分析-18-基于振动分析进行故障诊断的思路和步骤

参考树立正确的振动诊断思路 参考振动分析相关知识的储备及振动分析仪的局限性 参考如何进行振动分析诊断(译文) 1 正确的故障诊断意识 我们通常在学习班听到的是大学教授以及专家讲解的故障诊断的基础理论,对于刚接触这个专业的人来说,微分方程和复杂的矩阵却有点让人忘…

JeecgBoot低代码平台简单记录

BasicModal弹窗 Usage 由于弹窗内代码一般作为单文件组件存在&#xff0c;也推荐这样做&#xff0c;所以示例都为单文件组件形式 注意v-bind"$attrs"记得写&#xff0c;用于将弹窗组件的attribute传入BasicModal组件 attribute&#xff1a;是属性的意思&#xff0c;…

Spring全家桶(三):Spring AOP

Spring AOP面向切面编程 1.面向切面编程思维&#xff08;AOP&#xff09; 1.1.面向切面编程思想AOP AOP&#xff1a;Aspect Oriented Programming面向切面编程 AOP可以说是OOP&#xff08;Object Oriented Programming&#xff0c;面向对象编程&#xff09;的补充和完善。O…

一键生成专业PPT:2024年AI技术在PPT软件中的应用

不知道你毕业答辩的时候有没有做过PPT&#xff0c;是不是也被这个工具折磨过。没想到现在都有AI生成PPT的工具了吧&#xff1f;这次我就介绍几款可以轻松生成PPT的AI工具吧。 1.笔灵AIPPT 连接直达&#xff1a;​​​​​​​https://ibiling.cn/ppt-zone 这个工具我最早是…