索引下推与覆盖索引是什么?

考查重点:回表消除与索引层过滤。覆盖索引让所需列都在索引中而免回表;ICP 在回表前用索引已有列过滤,减少回表次数

本题目录

参考答案

核心回答

覆盖索引解决“是否需要回表取数据”:若查询需要的列都能从所用索引获得,就可以直接从索引返回,减少访问完整行。索引下推(ICP)解决“回表前能否先过滤”:存储引擎用索引里已有的列先判断可下推条件,只为通过筛选的记录读取完整行。

所以覆盖索引争取不回表,ICP争取少回表;它们不是同一个概念,也不是仅仅给索引换一个名字。

用同一索引理解区别

假设二级索引包含邮编和姓名。查询某邮编下、姓名中含某片段的用户,邮编可定位索引范围;姓名条件可能无法进一步缩小连续定位范围,但可在索引记录上筛选。若还要读取地址详情,ICP能先排除不匹配姓名的项,再对剩余项回表。

如果只返回索引中已有的邮编、姓名和主键ID,可能形成覆盖查询,通常无需为取得这些列再去聚簇索引读取完整记录。InnoDB二级索引包含主键,因此“返回列没有显式出现在索引定义里”也不一定需要回表。

沿着索引项到完整记录的访问路径,对照两种优化发生的位置:

覆盖查询直接从索引返回列,ICP先在索引筛选通过项再回表,未使用ICP则候选项先回表再判断

这里沿用正文的邮编、姓名二级索引和地址字段。覆盖取决于本次查询所需列,ICP取决于可下推条件;图不表示固定性能倍率。

怎样检查

执行计划中的Using index通常提示覆盖读取,Using index condition提示ICP。二者应结合所选索引、访问方式和返回列理解,不能看到Extra里出现index就认定整条查询高效。

MySQL8.4的ICP对InnoDB主要用于需要读取完整行的二级索引访问,并非所有表达式都能下推。若条件涉及索引没有的列,就不能仅靠该索引项判断;覆盖查询本身已避免相应的完整行读取,也不是再叠加一次ICP才更好。

追问

范围条件后的联合索引列不一定“完全失效”:它们可能不再帮助缩小定位范围,却仍可能用于ICP筛选或覆盖返回。应区分索引定位、索引过滤和结果覆盖这三种用途。

参考资料

相关面经

4 篇

水滴公司

AI 全栈工程师
校招秋招一面、二面
查看原面经 →
有没有什么办法让它不回表?

蚂蚁集团

面经合集
查看原面经 →
数据库索引下推的适用场景是什么?它能提升性能的原因是什么?

字节跳动

后端开发工程师(AI)
实习一面
查看原面经 →
分别讲讲索引下推、索引覆盖的概念。

字节跳动

AI 开发工程师
实习一面
查看原面经 →
索引覆盖原理

相关题目

4 题