能用,但得看怎么写——like 'abc%' 可走索引,like '%abc' 基本等于全表扫描;仅%和_是原生通配符,%匹配任意长字符串,_匹配单字符;前缀匹配可利用b+树索引,后缀或中间匹配则失效,需靠反向索引、全文索引等替代方案。

能用,但得看怎么写——LIKE 'abc%' 可走索引,LIKE '%abc' 基本等于全表扫描。
LIKE 通配符怎么写才不踩坑
只有两个通配符真正被 MySQL 原生支持:% 匹配任意长度(含零)字符串,_ 只匹配单个字符。别指望 ?、* 或正则语法直接生效。
-
'a%'→ 匹配以 a 开头的字符串,如'apple'、'a' -
'%a'→ 匹配以 a 结尾的,如'banana',但无法用普通索引加速 -
'a_b'→ 匹配三字符且首尾是 a/b、中间任一字符,如'axb'、'a2b' -
'a%b'→ 中间任意长度,name字段即使有索引也失效,B+ 树没法跳过未知段继续比对
大小写敏感和 NULL 值怎么处理
默认情况下,LIKE 是否区分大小写,取决于字段的排序规则(collation)。比如 utf8mb4_0900_ai_ci 不区分,utf8mb4_0900_as_cs 区分。
- 强制区分大小写:加
BINARY,如WHERE name LIKE BINARY 'Alice' -
NULL值永远不匹配任何LIKE模式,必须单独判断:WHERE name IS NULL OR name LIKE '%li%' - 字段值末尾空格是否参与匹配,也受 collation 控制;
utf8mb4_0900_as_cs会严格比对空格,而_ci类规则通常忽略
含 % 或 _ 的字面量怎么查
如果真要查用户名里带下划线的记录(比如 'user_name'),直接写 LIKE '%_%' 会匹配所有行——因为 _ 被当成了通配符。
- 用
ESCAPE指定转义字符,例如:WHERE name LIKE '%_%' ESCAPE '' - 也可换其他符号,比如
WHERE name LIKE '%!_%' ESCAPE '!' - 注意:转义字符本身若出现在数据中,也要写两遍,如查字符串
'a',模式得写成'a\b'(配合ESCAPE '')
为什么加了索引还是慢
建了 INDEX(name) 却发现 EXPLAIN 显示 type: ALL,大概率不是索引没建,而是查询写法或环境破坏了索引可用性。
- 字段类型与参数类型不一致:比如
name VARCHAR(50)却写成WHERE name LIKE 123,触发隐式转换 - 在字段上套函数:
WHERE UPPER(name) LIKE 'ABC%',除非你建了函数索引CREATE INDEX idx_upper_name ON t((UPPER(name))) - 用了
OR且分支之一无索引:WHERE name LIKE 'a%' OR status = 1,优化器常放弃索引 - 匹配结果太多(超过约 20% 总行数),优化器认为全表扫描更快,这时
rows值会异常高
真正影响性能的从来不是 LIKE 本身,而是它暴露的索引设计盲区和查询意图表达偏差——比如后缀匹配,与其硬扛 LIKE '%abc',不如提前存个 reversed_name 字段加索引,或者改用全文索引。











