SQL语句能否同时使用索引覆盖与ICP?非覆盖索引时InnoDB是否自动启用ICP?
索引覆盖与索引条件下推的常见问题解答
1. SQL语句是否可以同时应用索引覆盖和索引条件下推?
可以同时应用。
举个实际例子:假设学生表student有联合索引idx_name_age_score(name, age, score),执行以下SQL:
SELECT name, age FROM student WHERE name LIKE '张%' AND age > 20;
- 索引覆盖:查询需要的
name和age字段都在联合索引中,无需回表查询原表的其他数据。 - 索引条件下推:存储引擎在遍历索引时,会先过滤出
name以"张"开头的索引条目,接着直接在索引层判断age > 20的条件,只把符合两个条件的索引条目返回给服务器,全程不用回表。
两者在此场景下同时生效,既减少了回表操作,又提前过滤了不必要的数据。
2. 当查询不满足索引覆盖的条件时,InnoDB是否会自动启用索引条件下推?
不会自动启用,ICP的触发需要满足特定条件,核心前提是查询使用了二级索引,且存在可以在索引层判断的过滤条件,不满足索引覆盖只是其中一个基础前提。
举两个对比例子:
触发ICP的场景
同样用上面的联合索引,执行SQL:
SELECT * FROM student WHERE name LIKE '张%' AND age > 20;
这个查询需要返回所有字段(*),不满足索引覆盖,必须回表。此时age > 20的条件可以通过联合索引的第二列判断,InnoDB会启用ICP:在存储引擎层先过滤出name以"张"开头且age >20的索引条目,再根据这些条目中的主键回表查询完整数据,减少了回表的次数。
不触发ICP的场景
执行SQL:
SELECT * FROM student WHERE name LIKE '%张' AND age >20;
这个查询不满足索引覆盖,但name LIKE '%张'无法利用联合索引的前缀匹配,数据库根本不会走这个联合索引,自然也就不会触发ICP,只能全表扫描后再过滤条件。
通俗解释两种机制
- 索引覆盖:相当于查字典时,你要找的所有信息(比如某几个字的读音、笔画)都在字典的索引目录里,不用翻到正文页就能拿到结果,节省了翻页的时间。
- 索引条件下推:本来查字典时,你先把索引目录里所有偏旁符合的条目都列出来,再一个个翻正文页看笔画是否符合;ICP则是在索引目录里先把偏旁+笔画都符合的条目筛出来,再去翻正文,减少了翻正文的次数。
内容的提问来源于stack exchange,提问作者Lucien
相关产品推荐
相关产品推荐

