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

mysql优化-mysql索引下推

它的官方名称叫 ​Index Condition Pushdown,简称 ​ICP

核心目的

索引下推的核心目的是减少存储引擎层需要回表查询的次数,从而提升查询性能,特别是对于那些无法完全在索引中筛选数据行的查询。​

工作原理(对比开启/关闭ICP)

想象一个场景:你有一张表 users,上面有一个联合索引 idx_age_city (age, city)

现在你要执行这样一个查询:

SELECT * FROM users WHERE age > 25 AND city = 'Beijing';

1. 在没有开启 ICP 的情况下(MySQL 5.6 之前)

  1. 存储引擎(如 InnoDB):​

    • 使用索引 idx_age_city找到所有满足 age > 25条件的记录的主键值 (或定位到数据)。

    • 因为 city虽然是索引的第二列,但在 age > 25(范围条件)的情况下,存储引擎默认不能使用索引中 city列的条件进行进一步的过滤​(索引的最左前缀原理,范围条件会“截断”后续列的索引查找)。

    • 存储引擎需要根据每一个满足 age > 25的主键值,执行回表操作,读取完整的数据行(完整的 row)。

  2. MySQL 服务器层:​

    • 接收到存储引擎返回的所有满足 age > 25的完整数据行。

    • 服务器层自己负责应用 WHERE条件中剩下的 city = 'Beijing'进行过滤。

    • 最终返回符合所有条件 (age > 25 AND city = 'Beijing')的数据给客户端。

    • 问题:​​ 很多 age > 25的行,其 city可能不是 'Beijing'。但存储引擎仍然把它们全部读出来并传给服务器层,造成了大量不必要的回表 I/O 和网络传输。​

2. 在开启​ ICP 的情况下(MySQL 5.6 及之后默认开启)

  1. 存储引擎(如 InnoDB):​

    • 和之前一样,使用索引 idx_age_city找到所有满足 age > 25条件的记录。

    • 关键区别来了:​

      • MySQL 服务器层会将 WHERE子句中的过滤条件(尤其是那些属于该索引但无法被索引查找直接使用的部分,如本例中 city = 'Beijing')​​“下推”​​ 到存储引擎层。

      • 存储引擎在找到满足 age > 25的索引条目后,​不会立即回表​!

      • 存储引擎直接在索引(通常是二级索引的叶子节点,存储了 (age, city, 主键))上检查 city列是否等于 'Beijing'。​

      • 只有当一个索引条目同时满足 age > 25city = 'Beijing'(或者说满足下推的条件)时,存储引擎才会执行回表操作读取完整数据行。​

  2. MySQL 服务器层:​

    • 只接收存储引擎传回的、已经初步满足 age > 25 AND city = 'Beijing'条件的完整数据行

    • 服务器层再进行一些 ICP 无法处理的其他条件检查(比如涉及非索引列的计算或函数等),然后返回结果。

    • 优势:​​ ​显著减少了回表操作和传输给服务器层的数据量。​​ 很多 age > 25city不是 'Beijing'的行,在存储引擎层就被过滤掉了,根本不需要回表读取数据行,也不需要传输到服务器层处理。

图示简化流程

没有ICP:
索引(找 age>25) -> 回表取行 -> 给服务器 -> 服务器过滤 city='Beijing'开启ICP:
索引(找 age>25) -> 在索引上立即检查 city='Beijing'? -> Yes -> 回表取行 -> 给服务器 -> 服务器检查其他条件|VNo, 跳过此条!

ICP 能生效的关键点

  1. 索引类型:​​ ICP ​主要适用于二级索引(Secondary Index)​。主键索引(聚簇索引)本身包含了完整的数据行,无需回表,因此 ICP 对其无效。

  2. 查询类型:​​ 对 InnoDB表有效。

  3. 作用范围:​​ 适用于 SELECTUPDATEDELETE语句中需要访问完整表行的情况。如果查询只需要索引列(覆盖索引),那么即使存在其他条件,也不需要回表,ICP 的效果可能不明显或没有用武之地(因为数据已经通过索引返回了)。

  4. 条件位置:​

    • 被下推的条件部分必须能够通过索引列来评估。​

    • WHERE条件被划分为两部分:

      • 索引条件 (Index Condition):​​ 那些与索引列相关、能被存储引擎在索引上直接评估的条件(即使不能用于索引查找本身,如非最左前缀或等值匹配后的范围列)。

      • 表级条件 (Table Condition):​​ 那些不能通过索引评估的条件(如非索引列、索引列的复杂函数计算等)。

    • ICP 只处理索引条件部分。

如何判断查询是否使用了 ICP?

使用 EXPLAIN查看你的 SQL 执行计划。如果在 Extra列中看到 ​Using index condition,就表明 MySQL 对该查询使用了索引下推。

EXPLAIN SELECT * FROM users WHERE age > 25 AND city = 'Beijing';

可能的 Extra 输出:​

Using index condition  # 这代表使用了ICP
Using where            # 这代表服务器层应用了额外的表级条件过滤

性能提升

效果非常显著,尤其是当第一个索引列是范围条件且满足该范围条件的行数很多,但第二个索引列的条件具有高选择性(能过滤掉大量行)时。

官方文档(MySQL 8.0)提到在某些场景下性能提升可达几十倍甚至几百倍

总结

索引下推(ICP)是 MySQL 一项重要的查询优化技术,通过在存储引擎层对索引条件进行早期过滤,极大限度地减少了不必要的回表 I/O 操作和数据传输量,从而显著提升查询性能。它特别适用于使用联合索引时,WHERE子句中包含第一个索引列的范围条件以及后续索引列的等值/范围等条件的情况。理解 ICP 对于优化慢查询至关重要。

http://www.xdnf.cn/news/18794.html

相关文章:

  • LeetCode - 946. 验证栈序列
  • Linux-孤儿进程和僵死进程
  • mysql是怎样运行的(梳理)
  • Python包管理与安装机制详解
  • EasyExcel 3.x 导出动态表头,动态sheet页
  • Rust:函数与控制流
  • 《Java反射与动态代理详解:从原理到实践》
  • 【Ansible】Ansible部署K8s集群--准备环境--配置网络
  • PEFT 模型解析(59)
  • 《数据之心》——鱼小妖的觉醒
  • ctfshow_萌新web16-web20-----文件包含日志注入
  • 《信息检索与论文写作》实验报告二 引文索引数据库检索
  • 我们来学mysql -- safe启动
  • 解析xml文件并录入数据库
  • 类似ant design和element ui的八大Vue的UI框架详解优雅草卓伊凡
  • Vue中的scoped属性
  • 推荐系统王树森(三)粗排精排
  • 【NER学习笔记】:基于AdaSeq的NER模型训练笔记
  • Linux下TCPT通信
  • 8.26 支持向量机
  • 什么样的 IP 能穿越周期,持续被用户买单?​
  • 基于大模型的智能占卜系统实战-Qwen-VL、RAG、FastAPI
  • “喵汪联盟”宠物领养系统的设计与实现(代码+数据库+LW)
  • Python编程快速上手—让繁琐工作自动化
  • OpenCV打开视频函数VideoCapture使用详解
  • 数据与端点安全 (Protect data and apps)
  • 【学习笔记】系统时间跳变会影响time接口解决措施
  • Matlab使用——开发上位机APP,通过串口显示来自单片机的电压电流曲线,实现光伏I-V特性监测的设计
  • es-toolkit 是一个现代的 JavaScript 实用库
  • UE4生成Target文件