%匹配任意长度(含零个)字符,_只匹配严格一个字符;误用会导致结果偏差,如'张_'仅匹配两字姓名;需注意转义、索引失效、collation影响及NULL不匹配。

LIKE中%和_的匹配行为完全不同
%匹配任意长度(含零个)字符,_只匹配严格一个字符。写错通配符会导致结果完全偏离预期——比如想查“张”开头的所有人,却误写成WHERE name LIKE '张_',结果只返回两个字的名字(如“张三”),漏掉“张小明”“张建国”等。
常见误用场景:
- 用
_代替%做任意长度匹配(如查邮箱域名,email LIKE '%@gmail.com'正确,'%@gmail.com'语法错误且逻辑失效) - 在需要模糊中间段时仍用
_(如查“王_明”,本意是“王”+任意字+“明”,但_只占一位,无法匹配“王小明”“王大明”以外的变体) - 忽略
_对字段长度的硬性约束:若字段定义为VARCHAR(10),LIKE 'abc_______'(8个下划线)会自动截断或不匹配,而非“尽可能填满”
中文、特殊字符与ESCAPE转义必须显式处理
当搜索内容本身含%或_(如折扣率“95%”、用户名“a_b”),直接写rate LIKE '95%'会被解释为“以95开头的任意字符串”,不是字面匹配“95%”。必须用ESCAPE子句声明转义符。
实操要点:
- 转义符选
!、\或#均可,但需确保它不出现在待匹配文本中(例如ESCAPE '!'后,模式串里!%才表示字面%) - 方括号
[本身也是特殊字符,要匹配字面左括号,得写成'[[]',且这个替换必须最先做(否则后续规则会干扰) - SQL Server中单引号
'也要转义:参数值中的'需写成'',否则语法报错
前导%导致索引完全失效,性能陷阱藏在WHERE条件左侧
LIKE 'abc%'能走B-Tree索引,LIKE '%abc'或LIKE '%abc%'基本触发全表扫描。100万行表上执行title LIKE '%数据库%',响应时间可能从几毫秒跳到数秒。
可缓解但非根治的方案:
- 优先改用前缀匹配:
WHERE url LIKE 'https://%'比'%https://'快得多 - 字段较短(如6位订单号)时,建函数索引:
CREATE INDEX idx_order_lower ON orders ((lower(order_no))),再用LOWER(order_no) LIKE 'po2024%' - 真正需要任意位置匹配时,别硬扛——MySQL用
MATCH AGAINST,PostgreSQL用tsvector,或引入Elasticsearch
大小写和NULL值不按直觉工作,collation才是实际裁判
LIKE本身不决定大小写行为,字段的排序规则(collation)才起作用。MySQL用utf8mb4_general_ci默认不区分大小写,但换成utf8mb4_bin就区分;PostgreSQL默认区分,ILIKE才是不区分版本。
容易被忽略的细节:
-
col LIKE '%张%'在某些collation下不匹配“張”(繁体),这不是bug,是排序规则未覆盖Unicode变体 -
col LIKE '%'永远不返回NULL值,哪怕该字段有空记录;真要包含空值,必须显式加OR col IS NULL - 参数化查询中,pattern必须传带引号的字符串(如
'张%'),不能只传张%——少引号会导致语法错误或逻辑错乱
LIKE语法写不对。

















