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

news2024/9/22 15:37:00

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%' 进行最终过滤。
    据应用剩余条件 age > 30address LIKE '%Street%' 进行过滤。

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

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

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

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

相关文章

分布式事务原理

目录 第一节&#xff1a;分布式事务基础详细总结 1.1 事务的核心特性&#xff08;ACID&#xff09; 1.2 分布式事务的挑战 1.3 分布式事务的实现难点 1.4 分布式事务解决方案概览 图解&#xff1a;分布式事务的ACID特性 第二节&#xff1a;事务消息方案详细总结 2.1 事务…

AUTOSAR实战教程-使用DET来发现开发错误

2年之前因为在调试AUTOSAR存储协议栈的时候使用DET并没发现有用的信息,所以就武断下结论--这玩意没有用。活到老学到老吧,bug经历的多了,发现这玩意还挺有用的。说一下这个bug的背景。 在将时间同步报文改道CanTsync之后,由于这个AUTOSAR工具本身的问题以及配置工程师本身的…

SpringBoot校园社团场地租借平台开发-计算机毕业设计源码00746

摘 要 这个项目旨在开发一个基于SpringBoot 的校园社团场地租借平台&#xff0c;帮助学校社团更方便地租借校园内的场地。用户可以在平台上浏览不同场地的信息、预订场地、查看租借历史记录等。管理员可以管理场地信息、审批租借申请和生成报表统计等功能。通过该平台&#xff…

【大模型实战篇】搭建本地的隐私计算知识问答系统“密答”

1. 背景介绍 在之前分享的文章《基于开源大模型的问答系统本地部署实战教程》中&#xff0c;我们介绍了基于ollama实现本地问答系统的部署和使用。本文将基于ollama进一步实现本地垂直领域的问答系统搭建。ollama作为大模型的运行框架&#xff0c;可以提供大模型的使用接口…

Python 设计模式之建造者模式

文章目录 建造者模式中的简单版本逐渐复杂的问题建造者模式的实现 建造者模式中的经典版本 建造者&#xff08;builder&#xff09;模式属于创建型模式&#xff0c;建造者模式一般有两种类型的应用 建造者模式中的简单版本 逐渐复杂的问题 假设现在需要创建一个用户对象&…

如何提高小红书种草转化率

企业和品牌方想要在小红书上做种草推广一般分为图文种草和视频种草两种形式&#xff0c;而且小红书是一个完全可以依靠内容实现涨粉、变现、种草转化的平台&#xff01; 因为小红书是算法推荐制&#xff0c;将你的作品放在流量池中检测&#xff0c;满足要求就能进入下一个流量池…

Python酷库之旅-第三方库Pandas(061)

目录 一、用法精讲 236、pandas.Series.explode方法 236-1、语法 236-2、参数 236-3、功能 236-4、返回值 236-5、说明 236-6、用法 236-6-1、数据准备 236-6-2、代码示例 236-6-3、结果输出 237、pandas.Series.searchsorted方法 237-1、语法 237-2、参数 237-…

Linux 内核源码分析---插入和删除模块

模块是一种向 Linux 内核添加设备驱动程序、文件系统及其他组件的有效方法&#xff0c;不需编译新内核或重启系统。 模块具有如下优点&#xff1a; • 通过使用模块&#xff0c;内核发布者能够预先编译大量驱动程序&#xff0c;而不会致使内核映像的尺寸发生膨胀&#xff1b; …

PTA—基础编程题目集(7-18)

7-18 二分法求多项式单根 目录 题目描述 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 参考代码 总结 题目描述 输入在第1行中顺序给出多项式的4个系数a3​、a2​、a1​、a0​&#xff0c;在第2行中顺序给出区间端点a和b。题目保证多项式在给定区间…

60_1简单的学生管理系统【功能实现(查看所有学生(分页)、修改和删除学生信息)】

功能实现 老师角色查看所有学生 获取学生列表和分页 1.修改index.jsp 不能直接跳stuList.jsp&#xff0c;没数据 <%if("teacher".equals(role)){%><a href"TeaInitModifyServlet?username<%username%>">修改信息</a><a href…

设施农业“AutoML“时代:大模型自动调参,让农业算法模型更简单易用

&#xff08;于景鑫 北京市农林科学院智能装备技术研究中心&#xff09;设施农业是现代农业的重要发展方向,但在数字化、智能化的进程中仍面临诸多挑战。传统的农业算法模型虽然可以为设施农业提供一定的决策支持,但在实际应用中往往受限于参数调优复杂、模型泛化能力差等因素。…

<Rust><iced>基于rust使用iced构建GUI实例:一个CRC16校验码生成工具

前言 本专栏是Rust实例应用。 环境配置 平台:windows 软件:vscode 语言:rust 库:iced、iced_aw 概述 本文是专栏第五篇实例,是一个CRC16校验码转换程序。 本篇内容: 1、CRC16校验码生成 代码介绍 本文的crc16校验码生成工具,主要设计两个方面,一个是crc16 modbus…

PADS Router 扇出失败问题详细解决方法。

第一步&#xff1a;确定单位是一致的,我的单位是 “密尔”&#xff0c;不是“公制”。 第二步&#xff1a;进去pads router 右键选择特性&#xff0c;注意&#xff0c;是右键点击任意板框内空白位置的特性&#xff0c;这个是涵盖整体的设置&#xff0c;和单独点击一个元器件选…

react-native从入门到实战系列教程一Swiper组件的使用及bug修复

轮播图&#xff0c;在app中随处可见&#xff0c;这么重要的功能我们怎么可能不学习下在react-native中的实现方式。 依然是第三方组件react-native-swiper 官网地址 https://www.npmjs.com/package/react-native-swiper 组件使用的组件及事件参考官方即可。 实现效果 官网…

文件审查流程:使用指南

当您正在处理一个项目并且必须进行文档审查时&#xff0c;您可能会对这个过程到底涉及什么、谁是利益相关者以及审查过程的结果可能是什么感到困惑。在这篇博客文章中&#xff0c;让我们简单介绍一下文档审核过程及其对高质量内容的活力。 文件审查的定义 文件审查是文件经过…

CMD运行指令

CMD运行指令 开始→运行→CMD→键入以下命令即可: ASSOC显示或修改文件扩展名关联。 AT计划在计算机上运行的命令和程序。 ATTRIB显示或更改文件属性。 BREAK设置或清除扩展式CTRLC检查。 CACLS显示或修改文件的访问控制列表(ACLs)。 CALL从另一个批处理程序调用这一个。 CD显示…

不同类型游戏安全风险对抗概览(下)| FPS以及小游戏等外挂问题,一文读懂!

FPS 游戏安全问题 由于射击类游戏本身需要大量数值计算&#xff0c;游戏方会将部分计算存放于本地客户端&#xff0c;而这为外挂攻击者提供了攻击的温床。可以说&#xff0c;射击类游戏是所有游戏中被外挂攻击最为频繁的游戏类型。 根据网易易盾游戏安全部门检测数据显示&#…

未来十年机器人行业前景还好吗?

未来十年机器人行业的前景非常乐观&#xff0c;这一行业预计将持续快速发展并深刻影响我们的工作、生活和社会。以下是对未来十年机器人行业前景的详细分析&#xff1a; 一、技术驱动的创新与发展 1. 智能化与自主化&#xff1a;随着深度学习和神经网络技术的进步&#xff0c;…

MATLAB进阶:数据的拟合

几天我们继续深度学习MATLAB中的数据拟合 最小二乘拟合 假设已知经验公式yf(c,x)yf(c,x)&#xff08;c为参数&#xff0c;x为自变量&#xff09;&#xff0c;要求根据一批有误差的数据(xi,yi)&#xff0c;i0,1,...,n(xi​,yi​)&#xff0c;i0,1,...,n确定参数c。这样的问题称…

SSM大学生就业咨询管理系统-计算机毕业设计源码79442

目录 摘要 1 绪论 1.1 选题背景 1.2 研究目的和意义 1.3国内外研究现状 2系统分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 操作可行性分析 2.2 系统流程分析 2.2.1 数据流程 2.2.2 业务流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2…