instr和like在模糊查询中性能无本质区别,均因无法利用索引而全表扫描;真正影响性能的是查询模式是否支持前缀匹配,而非函数选择。

INSTR 和 LIKE 在模糊查询场景下性能几乎一样慢——只要涉及左模糊(%keyword 或 keyword 出现在任意位置),两者都走全表扫描,EXPLAIN 显示 type: ALL,没有本质区别。
为什么 INSTR 看起来“更高级”但不提速
很多人以为换函数就能绕过 LIKE 的性能瓶颈,其实是混淆了语法表达力和执行引擎能力。MySQL 对 INSTR()、LOCATE()、POSITION() 这类字符串位置函数不做索引下推;它们无法利用普通 B+ 树索引加速子串查找。
-
WHERE INSTR(name, '张')和WHERE name LIKE '%张%'在执行计划里 rows 数完全一致 - MySQL 8.0+ 虽支持函数索引,但必须显式创建:
CREATE INDEX idx_name_instr ON t ( (INSTR(name, '张')) ),且该索引只对固定子串有效,无法泛化 - 函数索引字段类型需严格匹配,比如
name是VARCHAR(50),索引定义里就不能用TEXT或隐式转换
右模糊时 LIKE 其实能走索引,INSTR 反而不能
当查询模式是前缀匹配(如 name LIKE '张%'),B+ 树索引天然支持范围扫描,type 可能为 range 或 ref;而 INSTR(name, '张') = 1 仍强制全表扫描,因为函数结果不可预测、无法下推到索引层。
- 右模糊
LIKE '张%'→ 可命中INDEX(name) -
INSTR(name, '张') = 1→ 即使语义等价,也不走索引 - 哪怕加了函数索引
(INSTR(name, '张')),也只能优化固定字符串,换一个字就失效
真正影响性能的是查询模式,不是函数名
决定是否全表扫描的关键是「能否利用索引做前缀匹配」,而不是你写了 LIKE 还是 INSTR。以下场景性能差异明显:
-
name LIKE '张%':高效,索引可用 -
name LIKE '%张':低效,全表扫描 -
name LIKE '%张%':低效,全表扫描 -
INSTR(name, '张') > 0:低效,全表扫描(和上一条无区别) -
name = '张':最快,type: const或ref
别在 INSTR 和 LIKE 之间纠结选哪个——该慢的一样慢。真要提速,得从架构入手:建前缀索引、上全文索引(FULLTEXT)、拆冗余字段(如提取拼音首字母)、或引入 Elasticsearch 等外部检索服务。函数写法只是表层,引擎不支持的事,换名字也没用。











