当前位置: 首页 > news >正文

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

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

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

相关文章:

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

1.索引失效的情况 以tb_user表举例&#xff0c;id为主键索引、name和phone字段上建立了一个普通索引&#xff0c;name和phone均为varchar类型。 索引列运算 当在 WHERE 子句或 JOIN 子句中对列使用函数或表达式时&#xff0c;索引会失效。 执行以下语句&#xff0c;可以发现执…...

1、爬⾍概述

1. 什么是爬虫&#xff1f; 爬虫&#xff08;Web Crawler&#xff09;是一种通过编写程序自动访问并提取互联网上数据的技术。爬虫可以帮助我们在浏览网页时自动收集和保存一些有用的数据&#xff0c;例如图片、视频和文本信息。简单来说&#xff0c;爬虫就是自动化的浏览器。…...

科普文:微服务之分布式链路追踪SkyWalking单点服务搭建

1. 概述 1.1 概念 SkyWalking 是什么&#xff1f; SkyWalking 极简入门 | Apache SkyWalking FROM Apache SkyWalking 分布式系统的应用程序性能监视工具&#xff0c;专为微服务、云原生架构和基于容器&#xff08;Docker、K8s、Mesos&#xff09;架构而设计。 提供分布式追…...

R 语言学习教程,从入门到精通,R的安装与环境的配置(3)

1、R 基础语法 一门新的语言学习一般是从输出 “Hello, World!” 程序开始&#xff0c;R 语言的 “Hello, World!” 程序代码如下&#xff1a; myString <- "Hello, World!" print ( myString )以上示例将字符串 “Hello, World!” 赋值给 myString 变量&#x…...

【Pageadmin】之cms漏洞

方法一&#xff1a;上传模块拿webshell 首页如下 第一步&#xff1a;访问admin/login&#xff0c;登录后台 第二步&#xff1a;使用哥斯拉工具生成payload 然后自动生成了一个asp的payload 第三步&#xff1a;上传文件 将asp文件压缩为压缩包&#xff0c;上传。 解压访问1.asp…...

AIGC重塑设施农业:让农事操作更智能,生产效率更高

设施农业是现代农业的重要组成部分,随着人工智能等前沿技术的快速发展,这个领域迎来了新的变革机遇。尤其是大语言模型(Large Language Model,LLM)技术的崛起,其强大的语言理解和知识汇聚能力,为设施农业智能化发展带来了新的想象空间。本文将深入探讨大模型技术在设施农业生产…...

netty应用-手写RPC

文章目录 手写RPC之案例定位与通信过程介绍RPC框架案例定位服务端与客户端架构通信过程1. 服务注册与发现2. 请求序列化与传输3. 请求处理与响应4. 响应反序列化与结果处理实现细节1. 服务端2. 客户端技术选型关键挑战总结手写RPC之请求响应通信协议定制协议结构示例消息头格式…...

私域流量变迁与精细移动化趋势下的AI智能名片小程序源码应用探索

摘要&#xff1a;随着移动互联网技术的飞速发展&#xff0c;私域流量的价值日益凸显&#xff0c;成为企业营销战略的重要组成部分。私域流量的精细化和移动化趋势不仅改变了传统的营销格局&#xff0c;也为新兴技术的应用提供了广阔空间。本文深入探讨了私域流量的变迁历程&…...

数据结构初阶之排序(下)

前言 上一期内容中我们了解了基本排序中的插入与选择排序&#xff0c;今天我将为大家带来剩下的几种排序算法 快速排序 快速排序是Hoare于1962年提出的⼀种⼆叉树结构的交换排序⽅法&#xff0c;其基本思想为&#xff1a;任取待排序元素序列中的某元素作为基准值&#xff0c;…...

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模拟/数字采样

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…...

C#裁剪图像的几种方法总结

前言 我们在上位机软件开发过程中经常需要裁剪图像&#xff0c;本文就是对c#中常见的裁剪图像方法进行总结。 1、克隆 直接调用Bitmap的Clone函数&#xff0c;然后指定需要裁剪的区域即可裁剪图像&#xff0c;该种方法不会损失精度 public static Bitmap CropImage_Clone(Bi…...

被遗忘的哑终端 —— 键盘键位演变的启发者

注&#xff1a;机翻&#xff0c;未校对。 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安装与应用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…...

预警器件控制思考

预警器件控制思考 最小示例思想 当读取到环境信息与环境阈值的时候, 我们预警系统就要根据这些信息做出判断,是否要启动器件。 最简单的就是&#xff0c; 举温度temp的例子, temp(温度)与temp_th(阈值), 通过判断, 得出是否要启动器件. 如果在一段时间内, 一直是环境异常, 我…...

[Day 43] 區塊鏈與人工智能的聯動應用:理論、技術與實踐

區塊鏈的隱私保護機制 隨著區塊鏈技術的廣泛應用&#xff0c;隱私保護成為了一個至關重要的問題。區塊鏈以其去中心化和透明性的特點&#xff0c;為數據管理和交易提供了新的方法。然而&#xff0c;這些特點也帶來了新的挑戰&#xff0c;尤其是在隱私保護方面。本文將深入探討…...

【星海随笔】路由器的启动过程

路由器的启动过程 1.加电之后&#xff0c;ROM运行加电自检程序&#xff08;Post&#xff09;&#xff0c;检查路由器的处理器、接口、内存等硬件设备。2.执行路由器中的启动程序(Bootstrap),搜索操作系统。路由器操作系统扩张部分可以从Flash RAM中装入&#xff0c;也可从 TFT…...

[翻译] Asset Administration Shells

关于资产管理外壳 (AAS) 资产管理外壳 (AAS) 是工业4.0中的关键概念&#xff0c;为产品、资源&#xff08;如设备&#xff09;和过程提供信息隐藏和更高层次的抽象。AAS 是技术和设备无关的机器可读描述&#xff0c;提供访问资产属性和功能的统一接口。与现有解决方案不同&…...

linux 常用磁盘维护命令

badblocks 功能说明&#xff1a;检查磁盘装置中损坏的区块。 语 法&#xff1a;badblocks [-svw][-b <区块大小>][-o <输出文件>][磁盘装置][磁盘区块数][启始区块] 补充说明&#xff1a;执行指令时须指定所要检查的磁盘装置&#xff0c;及此装置的磁盘区块数。…...

滑动窗口大总结!!!妈妈以后再也不担心我不会做滑动窗口啦~

写在前面&#xff1a;全部题都源于力扣 讲解题目一&#xff1a;最小覆盖子串题目二&#xff1a;字符串排列题目三&#xff1a;找所有字母异位词题目四&#xff1a;无重复字符的最长子串题目五&#xff1a;滑动窗口的最大值 讲解 滑动窗口算法技巧主要用来解决子数组问题&#…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中&#xff0c;如工厂高危作业区、医院手术室、公共场景等&#xff0c;人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式&#xff0c;存在效率低、覆盖面不足、判断主观性强等问题&#xff0c;难以满足对人员打手机行为精…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解

进来是需要留言的&#xff0c;先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码&#xff0c;输入的<>当成字符串处理回显到页面中&#xff0c;看来只是把用户输…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...