LIKE仅适用于简单模式匹配,前缀匹配(如'张%')可走索引、毫秒级响应,而'%张%'导致全表扫描;下划线\_严格匹配单字符,非可选;特殊字符需ESCAPE转义;大小写与collation相关;NULL值永不匹配LIKE。

直接说结论:LIKE 不是“万能模糊搜索”,它只适合简单模式匹配;用错通配符、忽略大小写规则或写上前导%,结果就可能漏数据、慢得离谱,甚至查出完全无关的记录。
WHERE name LIKE '张%' 和 WHERE name LIKE '%张%' 性能差十倍以上
前缀匹配(LIKE '张%')能走 B-Tree 索引,100 万行表通常毫秒级返回;而任意位置匹配(LIKE '%张%')基本触发全表扫描,尤其字段没建函数索引时。
- MySQL/PostgreSQL/SQL Server 都不例外——只要
%在开头,索引就失效 - 若必须后缀或中缀匹配,优先考虑:
MATCH AGAINST(MySQL 全文索引)、to_tsvector(PostgreSQL)、或把字段反向存储(如REVERSE(title)+ 索引 +LIKE '库据数%') - 加
LIMIT 100只是缓解,不是解决;真正慢的查询在EXPLAIN里一眼就能看到type: ALL
下划线 _ 不是“可选字符”,它强制匹配且只占一位
误写 WHERE name LIKE '张_' 想查“张”开头的所有人?实际只返回两字姓名(如“张三”),漏掉“张小明”“张建国”。_ 的语义是“严格一个任意字符”,不是“零个或一个”。
-
'张_'→ 匹配长度=2、首字为“张”的字符串 -
'张__'→ 强制长度=3,“张”+两个任意字 - 中文场景要小心:UTF-8 下一个汉字占 3 字节,但
_仍按“字符”计数,不是字节;字段定义为VARCHAR(10)时,'张_________'(9 个_)会因总长超限而无法匹配
查字符串里真有 % 或 _?必须用 ESCAPE 显式转义
想查折扣率字段值为 95% 的记录,写 rate LIKE '95%' 是错的——它会匹配 95abc、95、9500% 等所有以 95 开头的值,而非字面的 95%。
- 正确写法:
rate LIKE '95!%' ESCAPE '!'(用!转义),或rate LIKE '95\%' ESCAPE '\' - 转义符本身不能出现在待匹配文本中;若原文含
!,就得换别的(如#) - SQL Server 还要额外处理单引号:
name LIKE 'O''Reilly'才能匹配 “O’Reilly”
大小写到底分不分?别猜,看 collation
LIKE 本身不决定大小写行为,字段的排序规则(collation)才起作用。同一句 WHERE email LIKE '%GMAIL.COM',在不同库/不同字段上结果可能完全不同。
- MySQL:
utf8mb4_general_ci不区分,utf8mb4_bin区分;可临时用LOWER(email) LIKE LOWER('%gmail.com') - PostgreSQL:默认区分,要用
ILIKE才不区分 - SQL Server:取决于列 collation,也可统一用
WHERE UPPER(email) LIKE UPPER('%gmail.com') - 繁体简体问题更隐蔽:
LIKE '%张%'在utf8mb4_unicode_ci下不匹配“張”,这不是 bug,是 collation 设计如此
最易被忽略的点:NULL 值永远不匹配任何 LIKE 模式,哪怕写 col LIKE '%' IS NULL 也不行;真要包含空值,得显式加 OR col IS NULL。










