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

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.dtcms.com/a/352235.html

相关文章:

  • Python 将十进制转换为十六进制
  • Linux命令详解+示例(炫彩超全)
  • 2025秋招季:AI笔试破解大规模招聘难题
  • MySQL 面试题系列(四)
  • Pandas 分组聚合进阶:过滤与 apply
  • 【人工智能】神经网络的优化器optimizer(三):RMSProp动态自适应学习率优化器
  • java自定义注解实现
  • 开发electron时候Chromium 报 Not allowed to load local resource → 空白页。
  • 在使用spring ai进行llm处理的rag的时候,选择milvus还是neo4j呢?
  • gorm 枚举查询遇到的问题
  • 【Python】Python日志模块完全指南:从配置到常见错误排查
  • 深入OpenHarmony后台任务“黑匣子”:BackgroundTaskMgr框架全栈解析与实战避坑指南
  • C#编程:贪吃蛇游戏
  • 使用linux+javascript+html+mysql+nodejs+npm+express等构建信息资料采集系统
  • FreeRTOS 同步互斥与任务协作 学习笔记
  • 【Protues仿真】定时器
  • 对讲联动电梯门禁系统通过深度集成对讲、梯控、身份认证三大模块,在提升便捷性的同时,以“权限后置发放+电梯状态闭环检测“为核心,实现安全性与可靠性的双重突破。
  • 解决VSCode无法下载服务器端 Server问的题
  • 当 C++ 用于嵌入式开发:优点和缺点
  • .gitignore 文件相关使用配置
  • 【Redis】安装和基础命令
  • 十、Java面向对象编程入门指南:继承与多态
  • 利用 OpenTelemetry 建设尾部采样
  • 大模型全栈学习路线:4 - 6 个月从入门到实战,打通技术与业务闭环
  • [灵动微电子 霍尔FOC MM32BIN560C]从引脚到应用
  • 《黑客帝国》解构:白帽黑客的极客思维宇宙
  • vue3写一个简单的时间轴组件
  • 【python】python利用QQ邮箱SMTP发送邮件
  • k8s pod resources: {} 设置的含义
  • 支持向量机(第二十九节课内容总结)