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

【MySQL】索引下推减少回表次数

一、简述索引下推

“索引下推”是数据库领域的一个术语,主要出现在MySQL(尤其是InnoDB存储引擎)中,英文名叫 Index Condition Pushdown,简称 ICP。就是过滤的动作由下层的存储引擎层通过使用索引来完成,而不需要上推到Server层进行处理。ICP是在MySQL5.6之后完善的功能

二、举例

假设有个user_consum表,有主键索引id和联合索引(name, phone),id是用户的消费记录,一个用户有很多条消费记录且name是用户昵称,可能撞车:

CREATE TABLE `user_consum` (`id` int unsigned NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`phone` varchar(11) DEFAULT NULL,`gender` tinyint(1) DEFAULT NULL,`user_role` int DEFAULT 0,PRIMARY KEY (`id`)INDEX IDX_NAME_PHONE (name, phone)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

假设查询语句为:

SELECT * FROM user_innodb WHERE name = "luna" AND phone LIKE "%8848";

注意like是模糊匹配,无法用到索引。
此时假如在二级索引树中找到了几千个id即该用户有几千条消费记录,由于用户昵称可能撞车,这里不一定都是目标用户的,还需要手机尾号符合,那这里:

  • 1,在二级索引树查到符合name的id后,回表到聚簇索引树(主键索引树),回表查询几千次,这些id可能还是离散不连续的,即几千次随机磁盘IO;
  • 2,在存储引擎层查到几千行数据后,再将这些数据返到服务层根据过滤条件再筛选出尾号为8848的数据,发现其实只有10条数据符合

如果用上索引下推。
就是过滤的动作由下层的存储引擎层通过使用索引来完成,而不需要上推到Server层进行处理:
也就是在联合索引的查找中,即查找符合name = "luna"的数据,也直接在联合索引的叶子节点中去逐个判断phone的尾号是否为8848,然后找到那10条记录,再回表,从而将回表次数降低至10次!
在主键索引树中找到符合条件的10行数据后,再返给服务层10行,减少了存储引擎层到服务层的拷贝开销,也减轻了服务层的过滤处理压力

三、如何查看是否用到了索引下推

执行:

EXPLAIN SELECT * FROM user_innodb WHERE name = "luna" AND phone LIKE "%8848";

如果 Extra 字段出现 Using index condition,说明用了索引下推(ICP)。

四、ICP的意义

  • 减少回表次数,提升查询效率,尤其是对于大表和回表代价高的InnoDB表。
  • 减少存储层到服务层的拷贝开销,减轻服务层的处理压力
  • 只适用于InnoDB和MyISAM存储引擎(MySQL 5.6及以上版本)。

五、总结

索引下推(Index Condition Pushdown, ICP)是MySQL的一项索引优化技术,通过在索引遍历阶段尽量多地应用WHERE条件,减少回表次数,提高查询效率。

前置知识复习:

联合索引、最左匹配,回表、索引覆盖,

(1)联合索引:

(a,b)字段建立联合索引的话
按照a来进行排序,在a相等的情况下,才按b来排序

联合索引与最左匹配博客:
https://www.cnblogs.com/rjzheng/p/12557314.html

(2)最左匹配:

所谓最左原则指的就是如果你的 SQL 语句中用到了联合索引中的最左边的索引,那么这条 SQL 语句就可以利用这个联合索引去进行匹配,值得注意的是,当遇到范围查询(>、<、between、like前缀匹配)就会到此为止停止匹配(含当前这个)。
如有索引 KEY idx_abcd(a, b, c, d)
查询 WHERE a = 1 AND b = 2 AND c > 3 AND d = 4
a = 1 —— 用到了索引的第1列
b = 2 —— 用到了索引的第2列
c > 3 —— 范围查询(>),用到了索引的第3列
d = 4 —— 用不到索引,因为c是范围查询,后面的索引列就失效了 ,如果满足a = 1 AND b = 2 AND c > 3的行很多,那就要做很多匹配
所以sql应该这样写:WHERE a = 1 AND b = 2 AND d = 4 AND c > 3,这样都能用上索引
注意范围查询中like的情况

  • 如果是前缀匹配(比如LIKE ‘abc%’),能用到索引。
  • 如果是模糊匹配(比如LIKE ‘%6606’),无法走索引,因为无法确定起始位置,只能全表/全索引扫描
(3)回表

因为像联合索引还是单列普通索引这种非主键索引,都是查二级索引树,其value是主键id,所以如果要查一些在二级索引树没有的信息,就需要拿着主键id到聚簇索引(主键索引)树去查,这个过程就是回表。
回表的问题主要是,回表是一行数据回表一次,就要查一次聚簇索引!所以要想方法减少回表次数
比如假如查 select x from user where a=1 and c > 3; 其中x没有索引,a和c有索引,但是符合这个条件的有1000个数据,那回表会产生1000次查找,因为MySQL 只能从二级索引(idx_ac)中,依次取出每个满足条件的主键ID,每拿到一个主键值,就去聚簇索引树读取对应的整行数据,然后取出 x 字段。
因为二级索引返回的主键ID通常是离散的,这些主键对应的数据行物理上可能散布在磁盘不同位置,所以每次回表可能都需要一次磁盘I/O(如果不在缓冲池内),这就是“随机I/O”,效率低下(如果不离散的话倒是能直接在叶子节点顺序找到)

  • InnoDB接口设计:MySQL的存储引擎接口本身是逐行取主键再查主表,没有批量取一批主键一次返回多行的API(虽然理论上可以优化,但InnoDB的实现就是这样)。
  • 聚簇索引结构的限制:主表的行分散在磁盘不同位置,没办法保证物理上顺序访问,还是会有大量随机I/O。

也可以打开BKA批量回表机制(Batched Key Access ),比如每批次为500,那么对这500个主键id先排序,这样对于一些连续id就可以一次查找,减少随机I/O。注意:不是所有场景都能用BKA,主要在Join和二级索引回表时生效。
如果这种情况多,那最好就是给x也放到联合索引里,(a, c, x) — — 索引覆盖

(4)索引覆盖

如上user表里,如果

SELECT id, name,  phone FROM user_info WHERE name = "userxxxx";

因为name和phone是联合索引,而id是主键,所以直接在一次就能在联合索引树上查到所有信息,所以不会有回表,这就是索引覆盖

(5)SQL执行过程简述

大部分情况下,MySQL会先从存储层获取主键ID对应的完整行数据,然后在服务层根据过滤条件进行过滤

  1. SQL解析&优化(服务层)SQL语句先在服务层被解析、生成执行计划,决定使用哪个索引、如何访问数据。
  2. 存储引擎访问数据(存储层)执行计划下发到存储层(如InnoDB),存储层根据执行计划,从磁盘或缓存(Buffer Pool)中读取行数据。
  3. 返回数据到服务层过滤存储层把读到的数据行返回到服务层,服务层按照WHERE条件、HAVING条件等进行筛选、聚合等操作

相关文章:

【MySQL】索引下推减少回表次数

一、简述索引下推 “索引下推”是数据库领域的一个术语&#xff0c;主要出现在MySQL&#xff08;尤其是InnoDB存储引擎&#xff09;中&#xff0c;英文名叫 Index Condition Pushdown&#xff0c;简称 ICP。就是过滤的动作由下层的存储引擎层通过使用索引来完成&#xff0c;而…...

Artificial Analysis2025年Q1人工智能发展六大趋势总结

2025年第一季度人工智能发展六大趋势总结 ——基于《Artificial Analysis 2025年Q1人工智能报告》 趋势一&#xff1a;AI持续进步&#xff0c;竞争格局白热化 前沿模型竞争加剧&#xff1a;OpenAI凭借“o4-mini&#xff08;高智能版&#xff09;”保持领先&#xff0c;但谷歌&…...

DeepSeek模型高级应用:提示工程与Few-shot学习实战指南

引言 在DeepSeek模型的实际应用中,提示工程(Prompt Engineering)和Few-shot学习正成为提升模型性能的关键技术。相比全参数微调,这些技术能以更低成本实现领域适配。本文将深入解析DeepSeek模型的高级提示技巧、动态Few-shot实现方案,以及混合微调策略,帮助开发者在资源受…...

Android高级开发第三篇 - JNI异常处理与线程安全编程

Android高级开发第三篇 - JNI异常处理与线程安全编程 Android高级开发第三篇 - JNI异常处理与线程安全编程引言为什么要关注异常处理和线程安全&#xff1f;第一部分&#xff1a;JNI异常处理基础什么是JNI异常&#xff1f;检查和处理Java异常从C代码抛出Java异常异常处理的最佳…...

企业级应用狂潮:从Spotify到LinkedIn的Llama实战手册

当Spotify用Llama生成的个性化推荐文案让用户播放时长激增30%, 当LinkedIn靠开源框架将社交推荐延迟降低40%—— 企业级AI战场正经历从“技术炫技”到“利润引擎”的残酷蜕变。 核心数据:企业采用率爆发式增长(2025 Gartner调研) 指标2023年2025年增幅开源模型采用率42%87%…...

高效管理 Python 项目的 UV 工具指南

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 持续学习&#xff0c;不断…...

QT中子线程触发主线程弹窗并阻塞等待用户响应

目录 QT中子线程触发主线程弹窗并阻塞等待用户响应一、使用QMetaObject::invokeMethod实现子线程安全触发主线程弹窗并阻塞等待&#xff1a;&#x1f527; Qt多线程弹窗&#xff1a;安全阻塞等待方案&#xff08;QMetaObject::invokeMethod详解&#xff09;&#x1f9e0; 一、核…...

初识vue3(vue简介,环境配置,setup语法糖)

一&#xff0c;前言 今天学习vue3 二&#xff0c;vue简介及如何创建vue工程 Vue 3 简介 Vue.js&#xff08;读音 /vjuː/&#xff0c;类似 “view”&#xff09;是一款流行的渐进式 JavaScript 框架&#xff0c;用于构建用户界面。Vue 3 是其第三代主要版本&#xff0c;于 …...

HarmonyOS NEXT~鸿蒙开发工具CodeGenie:AI驱动的开发效率革命

HarmonyOS NEXT&#xff5e;鸿蒙开发工具CodeGenie&#xff1a;AI驱动的开发效率革命 一、CodeGenie概述 DevEco CodeGenie是华为鸿蒙开发生态中的一款AI辅助编程工具&#xff0c;集成于DevEco Studio IDE中&#xff0c;为开发者提供全方位的智能编程支持。这款工具通过AI技术…...

LeetCode-链表操作题目

虚拟头指针&#xff0c;在当前head的前面建立一个虚拟头指针&#xff0c;然后哪怕当前的head的val等于提供的val也能进行统一操作 203移除链表元素简单题 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(…...

【ARM】MDK浏览信息的生成对于构建时间的影响

1、 文档目标 用于了解MDK的代码浏览信息的生成对于工程的构建是否会产生影响。 2、 问题场景 客户在MDK中使用Compiler 5对于工程进行构建过程中发现&#xff0c;对于是否产生浏览信息会对于构建时间产生一定的影响。在Options中Output栏中勾选了Browse Information后&#…...

Python模块中__all__变量失效问题深度解析

文章目录 Python模块中__all__变量失效问题深度解析一、__all__ 的正确作用场景二、__all__ 不起作用的常见原因1. 未使用 from ... import \* 导入2. __all__ 定义不完整或错误3. 子模块未正确导出4. Python 解释器缓存问题5. 相对导入路径错误 三、解决方案1. 确保使用 from …...

py爬虫的话,selenium是不是能完全取代requests?

selenium适合动态网页抓取&#xff0c;因为它可以控制浏览器去点击、加载网页&#xff0c;requests则比较适合静态网页采集&#xff0c;它非常轻量化速度快&#xff0c;没有浏览器开销&#xff0c;占用资源少。当然如果不考虑资源占用和速度&#xff0c;selenium是可以替代requ…...

docker B站学习

镜像是一个只读的模板&#xff0c;用来创建容器 容器是docker的运行实例&#xff0c;提供了独立可移植的环境 https://www.bilibili.com/video/BV11L411g7U1?spm_id_from333.788.videopod.episodes&vd_sourcee60c804914459274157197c4388a4d2f&p3 目录挂载 尚硅谷doc…...

SpringBoot高校宿舍信息管理系统小程序

概述 基于SpringBoot的高校宿舍信息管理系统小程序项目&#xff0c;这是一款非常适合高校使用的信息化管理工具。该系统包含了完整的宿舍管理功能模块&#xff0c;采用主流技术栈开发&#xff0c;代码结构清晰&#xff0c;非常适合学习和二次开发。 主要内容 这个宿舍管理系…...

深度解析 Dockerfile 配置:构建高效轻量的FastAPI 应用镜像

目录 引言 Dockerfile构建FastAPI镜像的示例 一、基础镜像选择&#xff1a;轻量与安全优先 二、元数据声明&#xff1a;镜像维护者信息 三、依赖管理&#xff1a;分层构建与缓存优化 1. 复制依赖文件 2. 安装依赖 四、应用代码复制&#xff1a;最小化镜像内容 五、启动…...

ICASSP2025丨融合语音停顿信息与语言模型的阿尔兹海默病检测

阿尔兹海默病&#xff08;Alzheimers Disease, AD&#xff09;是一种以认知能力下降和记忆丧失为特征的渐进性神经退行性疾病&#xff0c;及早发现对于其干预和治疗至关重要。近期&#xff0c;清华大学语音与音频技术实验室&#xff08;SATLab&#xff09;提出了一种将停顿信息…...

[蓝桥杯]春晚魔术【算法赛】

目录 输入格式 输出格式 样例输入 样例输出 运行限制 解决思路 代码说明 复杂度分析 问题描述 在蓝桥卫视春晚的直播现场&#xff0c;魔术师小蓝表演了一个红包魔术。只见他拿出了三个红包&#xff0c;里边分别装有 A、B 和 C 个金币。而后&#xff0c;他挥动魔术棒&a…...

LeetCode - 965. 单值二叉树

目录 题目 深度优先搜索方法 正确的写法 题目 965. 单值二叉树 - 力扣&#xff08;LeetCode&#xff09; 深度优先搜索方法 什么是深度优先搜索&#xff1a;深度优先搜索(DFS)是一种图或树的遍历算法&#xff0c;它从起始节点开始&#xff0c;尽可能深地沿着一条路径探索&…...

LabVIEW杂草识别与精准喷洒

基于LabVIEW构建了一套集成机器视觉、智能决策与精准控制的农业杂草识别系统。通过高分辨率视觉传感器采集作物图像&#xff0c;利用 LabVIEW 的 NI Vision 模块实现图像颜色匹配与特征分析&#xff0c;结合 Arduino 兼容的工业级控制硬件&#xff0c;实现杂草定位与除草剂精准…...

分布式不同数据的一致性模型

1. 强一致性&#xff08;Strong Consistency&#xff09; 定义&#xff1a;所有节点在任何时间点看到的数据完全一致&#xff0c;读操作总是返回最近的写操作结果。特点&#xff1a; 写操作完成后&#xff0c;所有后续读操作都能立即看到更新。通常需要同步机制&#xff08;如…...

“application/json“,“text/plain“ 分别表示什么

这两个字符串&#xff1a;“application/json” 和 “text/plain” 是 MIME 类型&#xff08;媒体类型&#xff09;&#xff0c;用于告诉接收方消息内容的格式&#xff0c;它们出现在 ContentType 字段中。 它告诉系统或程序&#xff1a;“这段数据是什么格式&#xff1f;” 格…...

SQL: 窗口滑动(Sliding Window)

目录 什么是“窗口”&#xff1f; 什么是“滑动”&#xff1f; &#x1f50d; 滑动窗口的核心&#xff1a; &#x1f552; 什么是时间窗口&#xff1f;&#xff08;Time Window&#xff09; 时间窗口的基本结构 时间窗口的三种常见形式 &#x1f4ca; 什么是行窗口&…...

学习日记-day20-6.1

完成目标&#xff1a; 知识点&#xff1a; 1.集合_Collections集合工具类 方法:static <T> boolean addAll(Collection<? super T> c, T... elements)->批量添加元素 static void shuffle(List<?> list) ->将集合中的元素顺序打乱static <T>…...

【音视频】 FFmpeg 解码H265

一、概述 实现了使用FFmpeg读取对应H265文件&#xff0c;并且保存为对应的yuv文件 二、实现流程 读取文件 将H265/H264文件放在build路径下&#xff0c;然后指定输出为yuv格式 在main函数中读取外部参数 if (argc < 2){fprintf(stderr, "Usage: %s <input file&…...

Linux 系统 Docker Compose 安装

个人博客地址&#xff1a;Linux 系统 Docker Compose 安装 | 一张假钞的真实世界 本文方法是直接下载 GitHub 项目的 release 版本。项目地址&#xff1a;GitHub - docker/compose: Define and run multi-container applications with Docker。 执行以下命令将发布程序加载至…...

软件测试|FIT故障注入测试工具——ISO 26262合规下的智能汽车安全验证引擎

FIT&#xff08;Fault Injection Tester&#xff09;是SURESOFT专为汽车电子与工业控制设计的自动化故障注入测试工具​&#xff0c;基于ISO 26262等国际安全标准开发&#xff0c;旨在解决传统测试中效率低、成本高、安全隐患难以复现的问题&#xff0c;其核心功能包括&#xf…...

3D拟合测量水杯半径

1&#xff0c;目的。 测量水杯的半径 如图所示&#xff1a; 2&#xff0c;原理。 对 3D 点云对象 进行圆柱体拟合&#xff0c;获取拟合后的半径。 3&#xff0c;注意事项。 在Halcon中使用fit_primitives_object_model_3d进行圆柱体拟合时&#xff0c;输出的primitive_para…...

(21)量子计算对密码学的影响

文章目录 2️⃣1️⃣ 量子计算对密码学的影响 &#x1f30c;&#x1f50d; TL;DR&#x1f680; 量子计算&#xff1a;密码学的终结者&#xff1f;⚡ 量子计算的破坏力 &#x1f510; Java密码学体系面临的量子威胁&#x1f525; 受影响最严重的Java安全组件 &#x1f6e1;️ 后…...

Python训练打卡Day38

Dataset和Dataloader类 知识点回顾&#xff1a; Dataset类的__getitem__和__len__方法&#xff08;本质是python的特殊方法&#xff09;Dataloader类minist手写数据集的了解 在遇到大规模数据集时&#xff0c;显存常常无法一次性存储所有数据&#xff0c;所以需要使用分批训练的…...