LIKE查询仅前缀匹配(如'张%')可能走索引;'%三'、'%王%'及'_b%'等必全表扫描;MySQL 8.0+的Index Skip Scan不通用;中文模糊搜索应优先用全文索引或INSTR()替代。

LIKE 用 % 和 _ 做通配时,索引是否生效?
绝大多数情况下,LIKE 查询只有在**前缀匹配**(即模式以固定字符串开头,后接 %)时才可能走索引。例如:WHERE name LIKE '张%' 可能利用 name 字段的 B+ 树索引;但 WHERE name LIKE '%三' 或 WHERE name LIKE '%王%' 一定全表扫描。
原因在于 B+ 树索引按字典序存储,无法高效定位“结尾含某字符”或“中间含某字符”的记录。
- MySQL 8.0+ 对某些
LIKE '%abc'场景尝试使用 **Index Skip Scan**(需满足特定条件),但不通用,不可依赖 -
_表示单字符匹配,同样遵循前缀规则:只有LIKE 'a_b%'这类带明确前缀的才可能走索引 - 若字段是中文且用
utf8mb4,注意排序规则(如utf8mb4_0900_as_cs)会影响大小写和重音敏感性,进而影响匹配结果
中文模糊搜索时,LIKE 与全文索引、正则的区别
对中文文本做模糊查询,LIKE 本质是字节/字符逐位比对,不理解语义,也不支持分词。遇到多字词跨位置匹配(如“数据库优化”中查“优化数据库”)完全无能为力。
-
LIKE '%优化%'能匹配到,但性能差;LIKE '%优化数据库%'则要求两词连续出现,实际业务中几乎不成立 -
MATCH ... AGAINST()全文索引支持自然语言模式和布尔模式,但要求字段类型为TEXT/VARCHAR,且最小词长默认为 4(中文需配合ngram插件或改配置) -
REGEXP功能更强(如支持[一-龥]{2,}),但执行计划一律不走索引,且 CPU 开销远高于LIKE
SELECT * FROM article WHERE content REGEXP '[一-龥]{3}性能[一-龥]{1,2}';防止 SQL 注入时,LIKE 中的通配符怎么安全转义?
用户输入直接拼进 LIKE 模式字符串,会导致 %、_ 被当作通配符执行,也可能引发注入。不能只过滤,必须显式声明转义字符并统一处理。
- 用
ESCAPE子句指定转义符,例如:WHERE title LIKE '\%error\%' ESCAPE '\' - 应用层处理时,对用户输入中的
\、%、_统一加转义符(如反斜杠),再传入 SQL - 更稳妥的方式是改用参数化查询 +
CONCAT()构造模式:WHERE title LIKE CONCAT('%', ?, '%')—— 此时 ? 占位符内容不会被解释为通配符
当需要“包含多个关键词任意顺序”时,LIKE 已经不够用了
比如搜索“mysql 索引 优化”,要求标题中同时出现这三个词(不要求顺序或相邻),LIKE 必须写成三个 AND 条件:title LIKE '%mysql%' AND title LIKE '%索引%' AND title LIKE '%优化%',可读性差、无法利用索引、且容易漏匹配(如“MySQL调优”里没“索引”二字)。
- 这种需求应转向
MATCH ... AGAINST('+mysql +索引 +优化' IN BOOLEAN MODE) - 若无法改用全文索引,至少用
INSTR()替代部分LIKE(如INSTR(title, 'mysql') > 0),函数虽不走索引,但语义更清晰,也避免通配符干扰 - 注意
INSTR()区分大小写取决于字段排序规则,而LIKE默认不区分(除非用_cs规则)
真正难的不是写对一个 LIKE 表达式,而是判断它该不该出现在这里——尤其当字段数据量过 10 万、响应延迟开始波动时,那个 LIKE '%关键词%' 往往就是根因。










