LIKE适合简单包含匹配但%开头会导致全表扫描,REGEXP语义更准却性能差,LOCATE/INSTR是高效“包含”查询优选方案,中文需注意分词与编码。

用 LIKE 查询包含特定字符的字段
直接用 LIKE 是最常用、也最直观的方式,适用于模糊匹配场景。注意通配符的位置决定匹配逻辑:% 放前后表示“任意位置包含”,只放后面是“以某字符开头”,只放前面是“以某字符结尾”。
常见错误是忘记加 %,比如写成 WHERE name LIKE 'abc',这其实等价于 = 'abc',不是“包含”,而是“完全相等”。
-
SELECT * FROM users WHERE username LIKE '%admin%';→ 查所有用户名含admin的记录 -
SELECT * FROM logs WHERE message LIKE 'ERROR%';→ 查以ERROR开头的日志 - 如果要查包含下划线
_或百分号%本身,得用ESCAPE:例如LIKE '%100\%%' ESCAPE '\'
用 REGEXP 处理更复杂的字符模式
当需求超出简单子串匹配,比如“包含数字和字母组合”“至少两个连续空格”“不区分大小写的中文+英文混合”,就得上 REGEXP(MySQL 8.0+ 默认支持,5.7 也支持但语法稍弱)。
它比 LIKE 灵活,但性能通常更低,尤其在没索引的字段上全表扫描明显变慢。
-
SELECT * FROM products WHERE description REGEXP 'high.*speed';→ 中间允许任意字符 -
SELECT * FROM emails WHERE address REGEXP '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$';→ 粗略校验邮箱格式(不推荐替代应用层验证) - 注意:MySQL 的
REGEXP默认大小写不敏感;如需敏感,用REGEXP BINARY
中文、emoji 或多字节字符要注意 COLLATION
如果字段是 utf8mb4 编码但排序规则是 utf8mb4_general_ci,某些 emoji 或生僻汉字可能被截断或比较异常;LIKE 和 REGEXP 都受此影响。
查含中文的记录时,别假设 '%你好%' 总能命中——先确认字段实际存储的是完整 UTF-8 字符,且没有被前端或 ORM 截断。
- 检查字段定义:
SHOW CREATE TABLE mytable;看CHARACTER SET和COLLATE - 临时强制编码匹配:
WHERE name COLLATE utf8mb4_unicode_ci LIKE '%搜索词%' - emoji 存储必须用
utf8mb4,否则会变成???,再怎么查也找不到
性能差?先看有没有索引可用
LIKE '%xxx' 或 LIKE '%xxx%' 基本无法走索引(前导通配符),哪怕字段上有索引也会全表扫描。这是最容易被忽略的性能陷阱。
真正能走索引的只有 LIKE 'xxx%' 这种前缀匹配,前提是索引字段是查询的最左前缀。
- 想加速
%xxx%类查询,可考虑:全文索引(FULLTEXT)、倒排索引(如 Elasticsearch)、或冗余生成关键词列并建索引 -
EXPLAIN SELECT ...一定要跑一遍,看type是不是ALL(全表扫描) - 小表无所谓,但百万级以上数据量时,没索引的
LIKE '%keyword%'可能卡住整个连接池
实际执行前,先确认字符是否真在字段里——用 SELECT HEX(column) 看原始字节,有时候你以为的空格其实是 \u00A0(不间断空格),或者换行符混在中间。











