like 'abc%'跳过索引下推的常见情况包括:icp被禁用、字段为char类型导致空格不匹配、排序规则不支持前缀比较、查询中使用函数或隐式转换、联合索引未满足最左前缀原则、mysql版本低于5.6或非innodb引擎。

MySQL 的 LIKE 'abc%' 查询本身可以利用索引下推(ICP),但“无法利用”通常是因为 ICP 被禁用、条件不满足触发前提,或优化器主动绕过了它——不是 ICP 不支持,而是你没让它生效。
哪些情况下 LIKE 'abc%' 会跳过索引下推?
索引下推(Index Condition Pushdown)是 MySQL 5.6+ 引入的优化机制,它允许存储引擎在读取索引记录时就过滤掉不满足 WHERE 条件的行,减少回表次数。但 ICP 对 LIKE 有明确限制:
- 只对
LIKE 'prefix%'形式生效,LIKE 'ab%c'或LIKE '%abc'不触发 ICP(连索引都走不了,更别说下推) - 字段必须是
VARCHAR或TEXT类型且建了普通 B+ 树索引;CHAR类型因尾部空格问题,常导致 ICP 判定失败 - 排序规则(collation)必须支持快速前缀比较,比如
utf8mb4_bin或utf8mb4_0900_as_cs;utf8mb4_0900_ai_ci在某些版本中会抑制 ICP - 如果查询中混用了函数(如
UPPER(name) LIKE 'ABC%')、隐式转换(如name = 123)或联合索引未命中最左前缀,ICP 直接失效
如何确认 ICP 是否实际启用?
别只看 EXPLAIN 的 key 和 type,关键要看 Extra 字段是否含 Using index condition:
EXPLAIN SELECT * FROM users WHERE name LIKE 'john%';
若返回结果中 Extra 是 Using where,说明条件是在 Server 层过滤的;若是 Using index condition,才表示 ICP 生效。
- 如果没看到
Using index condition,先检查optimizer_switch中index_condition_pushdown是否为on:SELECT @@optimizer_switch; - 再确认该索引是否为
BTREE类型(FULLTEXT或SPATIAL索引不支持 ICP) - 注意:即使 ICP 开启,若优化器估算回表成本极低(比如覆盖索引已含所有 SELECT 字段),也可能跳过 ICP,直接走
Using index
为什么加了索引、写了 'abc%',EXPLAIN 却显示 Using where?
这往往意味着 MySQL 把 LIKE 当成了纯字符串匹配,而非可下推的范围条件。常见原因包括:
- 字段定义为
CHAR(20),而值存的是'abc'(实际占位'abc '),LIKE 'abc%'在 collation 比较时无法与索引项对齐,优化器放弃 ICP - 查询字面量未声明 collation,例如字段是
utf8mb4_0900_as_cs,但写的是WHERE name LIKE 'Abc%',大小写不一致导致无法做前缀剪枝 - 联合索引为
(status, name),但查询只写了WHERE name LIKE 'abc%'—— 索引根本没被用于查找,ICP 自然无从谈起 - MySQL 版本低于 5.6,或使用了 MyISAM 引擎(ICP 仅 InnoDB 支持)
ICP 不是银弹。它只在“索引能定位 + 条件可提前判断”的交集里起作用。很多线上慢查询看似用了 LIKE 'xxx%',实则因字段类型、collation 或索引设计偏差,让 ICP 始终处于休眠状态——得一行行核对 EXPLAIN 的 Extra 和实际字段定义,而不是默认它一定开着。











