【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 的查询执行流程通常是:
- 索引扫描:存储引擎使用索引查找满足索引条件的记录。
- 返回记录:将这些记录返回给 MySQL 服务器。
- 行过滤:MySQL 服务器根据剩余的查询条件进一步过滤这些记录。
使用索引下推后,MySQL 优化器会在索引扫描阶段尽可能多地应用查询条件,只有在通过索引扫描无法完全过滤的情况下,才进行回表操作。
适用场景
索引下推在以下场景中尤其有效:
- 范围查询:对索引列进行范围查询时,例如
BETWEEN、<、>等。 - 联合索引查询:在联合索引的前缀列上进行查询,并且查询条件涉及非索引列时。
- 复杂条件查询:查询条件包含多个过滤条件时,例如
AND、OR等。
示例
假设有一个包含联合索引 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 会:
- 使用索引
idx_name_age找到name = 'John'的所有记录。 - 回表读取每一条记录的实际数据。
- 对回表后的数据应用剩余条件
age > 30和address LIKE '%Street%'进行过滤。
在启用索引下推的情况下,MySQL 会:
- 使用索引
idx_name_age找到name = 'John'且age > 30的记录(在索引扫描阶段应用部分条件)。 - 仅对符合前两个条件的记录进行回表操作。
- 对回表后的数据应用剩余条件
address LIKE '%Street%'进行最终过滤。
据应用剩余条件age > 30和address LIKE '%Street%'进行过滤。
在启用索引下推的情况下,MySQL 会:
- 使用索引
idx_name_age找到name = 'John'且age > 30的记录(在索引扫描阶段应用部分条件)。 - 仅对符合前两个条件的记录进行回表操作。
- 对回表后的数据应用剩余条件
address LIKE '%Street%'进行最终过滤。
相关文章:
【MySQL】全面剖析索引失效、回表查询与索引下推
1.索引失效的情况 以tb_user表举例,id为主键索引、name和phone字段上建立了一个普通索引,name和phone均为varchar类型。 索引列运算 当在 WHERE 子句或 JOIN 子句中对列使用函数或表达式时,索引会失效。 执行以下语句,可以发现执…...
1、爬⾍概述
1. 什么是爬虫? 爬虫(Web Crawler)是一种通过编写程序自动访问并提取互联网上数据的技术。爬虫可以帮助我们在浏览网页时自动收集和保存一些有用的数据,例如图片、视频和文本信息。简单来说,爬虫就是自动化的浏览器。…...
科普文:微服务之分布式链路追踪SkyWalking单点服务搭建
1. 概述 1.1 概念 SkyWalking 是什么? SkyWalking 极简入门 | Apache SkyWalking FROM Apache SkyWalking 分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。 提供分布式追…...
R 语言学习教程,从入门到精通,R的安装与环境的配置(3)
1、R 基础语法 一门新的语言学习一般是从输出 “Hello, World!” 程序开始,R 语言的 “Hello, World!” 程序代码如下: myString <- "Hello, World!" print ( myString )以上示例将字符串 “Hello, World!” 赋值给 myString 变量&#x…...
【Pageadmin】之cms漏洞
方法一:上传模块拿webshell 首页如下 第一步:访问admin/login,登录后台 第二步:使用哥斯拉工具生成payload 然后自动生成了一个asp的payload 第三步:上传文件 将asp文件压缩为压缩包,上传。 解压访问1.asp…...
AIGC重塑设施农业:让农事操作更智能,生产效率更高
设施农业是现代农业的重要组成部分,随着人工智能等前沿技术的快速发展,这个领域迎来了新的变革机遇。尤其是大语言模型(Large Language Model,LLM)技术的崛起,其强大的语言理解和知识汇聚能力,为设施农业智能化发展带来了新的想象空间。本文将深入探讨大模型技术在设施农业生产…...
netty应用-手写RPC
文章目录 手写RPC之案例定位与通信过程介绍RPC框架案例定位服务端与客户端架构通信过程1. 服务注册与发现2. 请求序列化与传输3. 请求处理与响应4. 响应反序列化与结果处理实现细节1. 服务端2. 客户端技术选型关键挑战总结手写RPC之请求响应通信协议定制协议结构示例消息头格式…...
私域流量变迁与精细移动化趋势下的AI智能名片小程序源码应用探索
摘要:随着移动互联网技术的飞速发展,私域流量的价值日益凸显,成为企业营销战略的重要组成部分。私域流量的精细化和移动化趋势不仅改变了传统的营销格局,也为新兴技术的应用提供了广阔空间。本文深入探讨了私域流量的变迁历程&…...
数据结构初阶之排序(下)
前言 上一期内容中我们了解了基本排序中的插入与选择排序,今天我将为大家带来剩下的几种排序算法 快速排序 快速排序是Hoare于1962年提出的⼀种⼆叉树结构的交换排序⽅法,其基本思想为:任取待排序元素序列中的某元素作为基准值,…...
RGB图像的读取与保存
目录 1、安装imageio 2、读取照片 3、保存照片 4、resize 5、示例代码 1、安装imageio pip install imageio -i https://pypi.tuna.tsinghua.edu.cn/simple 2、读取照片 import imageio img imageio.imread(image_path) 3、保存照片 import imageio import numpy as…...
江协科技51单片机学习- p35 AD/DA模拟/数字采样
🚀write in front🚀 🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝…...
C#裁剪图像的几种方法总结
前言 我们在上位机软件开发过程中经常需要裁剪图像,本文就是对c#中常见的裁剪图像方法进行总结。 1、克隆 直接调用Bitmap的Clone函数,然后指定需要裁剪的区域即可裁剪图像,该种方法不会损失精度 public static Bitmap CropImage_Clone(Bi…...
被遗忘的哑终端 —— 键盘键位演变的启发者
注:机翻,未校对。 The Forgotten World of Dumb Terminals 被遗忘的哑终端世界 A quick journey through the lost age of “glass teletypes.” 快速穿越失落的“玻璃电传打字机”时代。 From the earliest days of digital computers, researchers o…...
APACHE安装与应用
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…...
预警器件控制思考
预警器件控制思考 最小示例思想 当读取到环境信息与环境阈值的时候, 我们预警系统就要根据这些信息做出判断,是否要启动器件。 最简单的就是, 举温度temp的例子, temp(温度)与temp_th(阈值), 通过判断, 得出是否要启动器件. 如果在一段时间内, 一直是环境异常, 我…...
[Day 43] 區塊鏈與人工智能的聯動應用:理論、技術與實踐
區塊鏈的隱私保護機制 隨著區塊鏈技術的廣泛應用,隱私保護成為了一個至關重要的問題。區塊鏈以其去中心化和透明性的特點,為數據管理和交易提供了新的方法。然而,這些特點也帶來了新的挑戰,尤其是在隱私保護方面。本文將深入探討…...
【星海随笔】路由器的启动过程
路由器的启动过程 1.加电之后,ROM运行加电自检程序(Post),检查路由器的处理器、接口、内存等硬件设备。2.执行路由器中的启动程序(Bootstrap),搜索操作系统。路由器操作系统扩张部分可以从Flash RAM中装入,也可从 TFT…...
[翻译] Asset Administration Shells
关于资产管理外壳 (AAS) 资产管理外壳 (AAS) 是工业4.0中的关键概念,为产品、资源(如设备)和过程提供信息隐藏和更高层次的抽象。AAS 是技术和设备无关的机器可读描述,提供访问资产属性和功能的统一接口。与现有解决方案不同&…...
linux 常用磁盘维护命令
badblocks 功能说明:检查磁盘装置中损坏的区块。 语 法:badblocks [-svw][-b <区块大小>][-o <输出文件>][磁盘装置][磁盘区块数][启始区块] 补充说明:执行指令时须指定所要检查的磁盘装置,及此装置的磁盘区块数。…...
滑动窗口大总结!!!妈妈以后再也不担心我不会做滑动窗口啦~
写在前面:全部题都源于力扣 讲解题目一:最小覆盖子串题目二:字符串排列题目三:找所有字母异位词题目四:无重复字符的最长子串题目五:滑动窗口的最大值 讲解 滑动窗口算法技巧主要用来解决子数组问题&#…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...
土建施工员考试:建筑施工技术重点知识有哪些?
《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目,核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容,附学习方向和应试技巧: 一、施工组织与进度管理 核心目标: 规…...
STM32标准库-ADC数模转换器
文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”:输入模块(GPIO、温度、V_REFINT)1.4.2 信号 “调度站”:多路开关1.4.3 信号 “加工厂”:ADC 转换器(规则组 注入…...
webpack面试题
面试题:webpack介绍和简单使用 一、webpack(模块化打包工具)1. webpack是把项目当作一个整体,通过给定的一个主文件,webpack将从这个主文件开始找到你项目当中的所有依赖文件,使用loaders来处理它们&#x…...
