Using index condition 表示MySQL启用了ICP,将部分WHERE条件下推至存储引擎层在二级索引遍历时过滤,需满足索引列连续、条件可纯索引计算等要求。

Using index condition 出现在 EXPLAIN 的 Extra 里,说明 MySQL 正在用 ICP
它不是“用了索引”的模糊信号,而是明确告诉你:MySQL 把部分 WHERE 条件下推到了 InnoDB(或 MyISAM)存储引擎层,在遍历二级索引时就做了过滤,而不是等回表后才判断。
典型表现是:type 是 ref 或 range,key 显示用了某个联合索引,Extra 同时出现 Using index condition —— 这说明前导列定位了索引范围,后续列的条件被下推执行了。
- 只对二级索引生效;主键/聚簇索引上不会出现这个提示
- 不改变索引是否“被使用”的判断逻辑,
key_len依然只反映最左匹配长度 - 如果
EXPLAIN里只有Using where,说明所有过滤都在 Server 层做,没启用 ICP 或条件不满足下推要求
哪些 WHERE 条件能被 ICP 下推?关键看能不能“纯索引字段算”
ICP 要求条件能由索引字段独立计算,不依赖聚簇索引行数据,也不触发隐式转换或函数调用。
- ✅ 可下推:
c = 10、c IN (1,2,3)、c > 5、c BETWEEN 1 AND 100、c LIKE 'abc%'(前缀匹配) - ❌ 不可下推:
UPPER(c) = 'ABC'、c + 1 > 10、c IN (SELECT x FROM t2)、address LIKE '%北京%'(非索引列)、NOW() > create_time - ⚠️ 隐式转换会直接让 ICP 失效:比如索引列是
VARCHAR,但写成WHERE c = 123(数字比较),引擎无法安全下推
联合索引顺序和查询写法,决定 ICP 能不能真正起效
ICP 不是“只要字段在索引里就能用”,它严格依赖索引列的连续性和查询条件的书写顺序。
- 索引
(a, b, c),查询WHERE a = 1 AND c = 3:只有a = 1用于定位,c = 3无法下推(b缺失,中断连续性) - 索引
(a, b, c),查询WHERE a = 1 AND b > 10 AND c = 5:三者都可能下推,因为a和b构成有序扫描区间,c是紧随其后的连续列 - 索引
(status, create_time, user_id),查询WHERE status = 'active' AND create_time > '2024-01-01':高收益场景,create_time的范围过滤能显著减少回表数 - 即使写了
ORDER BY c LIMIT 10,只要c在索引中且位置连续,ICP 对它的等值或范围条件依然有效
ICP 不一定加速,验证真实收益得看状态变量和实际扫描量
Using index condition 出现在 EXPLAIN 里,只是启用信号,不代表性能提升。低选择性条件反而可能增加 CPU 开销。
- 关掉 ICP 对比:
SET optimizer_switch='index_condition_pushdown=off'; EXPLAIN ...,看rows预估是否变大、Extra是否变成Using where - 查真实效果:
SHOW STATUS LIKE 'Handler_read_%';关注Handler_read_next(索引遍历次数)和Handler_icp_attempts(ICP 尝试次数):若后者接近前者,说明 ICP 真正在过滤;若Handler_read_next没明显下降,说明下推条件基本没筛掉数据 - 特别注意:如果查询本身已覆盖索引(
Using index),根本不需要回表,ICP 就完全无用武之地
Using index condition 就以为优化到位了,其实更关键的是确认下推的条件有没有真正过滤掉数据,以及那个联合索引的列序是不是真为这个查询服务的。


















