引言
朋友,写SQL查询时,LIKE绝对是逃不开的。但很多人对它的印象只有%,遇到复杂一点的匹配就抓瞎,甚至写出一堆性能灾难。
其实,SQL Server的LIKE里只有少数几个通配符,但用对了,模糊查询也能既优雅又高效。今天一次给你讲透,文末还有工程级的优化建议,绝对干货。
1. % —— 最常用,但最危险
含义:匹配任意长度的任意字符(包括0个字符)。
-- 以A开头(A, Abc, A123...)
WHERE name LIKE 'A%'
-- 包含A(前后随意)
WHERE name LIKE '%A%'
-- 以A结尾
WHERE name LIKE '%A'
⚠️ 灵魂警告:'%A%' 几乎无法使用索引,数据量大必走全表扫描。低频、小表、管理后台查询用用可以,核心业务接口慎用。
2. _ —— 位置敏感的精确占位
含义:匹配任意单个字符(必须占一位,不能多不能少)。
-- A + 1个字符(A1, Ab, 但 A 或 ABc 不行)
WHERE name LIKE 'A_'
-- 任意两个字符 + A(12A, xA? 不对,是两位 + A)
WHERE name LIKE '__A'
最佳实践:适合结构化编码的模糊匹配。比如固定格式的病案号 'P_2023_001'、项目编号 'A_B',能精准定位。
3. [ ] —— 字符集合与范围(SQL Server独有特色)
这是SQL Server相比其他数据库的一个实用增强。
3.1 枚举匹配
-- 只匹配 A123, B123, C123
WHERE name LIKE '[ABC]123'
3.2 范围匹配
-- 大写字母开头
WHERE name LIKE '[A-Z]%'
-- 数字开头
WHERE name LIKE '[0-9]%'
3.3 排除匹配(很实用)
-- 不以A开头的所有记录
WHERE name LIKE '[^A]%'
实战场景:日志表里快速过滤掉正常前缀的编码,找出异常脏数据。[ ] 配合 _ 和 %,能写出很精巧的规则校验。
4. ESCAPE —— 当你要匹配特殊符号本身
业务数据里真的会出现%或_作为普通字符(比如折扣率10%,标题README.md)。
-- 查找包含百分号%的记录
WHERE name LIKE '%\%%' ESCAPE '\'
ESCAPE 定义了转义符,\% 就被视为普通字符%。同样的逻辑也用于_和[。
⚠️ 一个必须知道的真相
SQL Server 的 LIKE:
- 不支持正则表达式
- 全文索引是另外一套
CONTAINS/FREETEXT,不要搞混
LIKE就是简单的模式匹配,别指望它做复杂文本分析。
🔥 工程经验:如何避免 LIKE 变成性能杀手
你在系统设计里(比如质控、匹配系统)一定要有这个意识:
| 写法 | 性能 | 适用场景 |
|---|---|---|
LIKE 'abc%' | ✅ 可用索引(前缀匹配) | 自动补全、编码前缀查询 |
LIKE '%abc' | ❌ 无法用索引 | 几乎总需规避,可考虑反向建字段 |
LIKE '%abc%' | ❌❌ 全表扫描 | 小表、低频管理后台、一次性分析 |
LIKE '[A-Z]%' | ✅ 范围开头仍可用索引 | 字母分类过滤 |
优化三板斧:
- 能前缀就用前缀:
LIKE 'abc%'是唯一好走的LIKE。 %abc%必须用 → 考虑换方案:- SQL Server 全文索引(
CONTAINS) - 专为模糊搜索设计的 Elasticsearch
- 业务层面限制查询范围(加日期、分类条件)
- SQL Server 全文索引(
- 反向索引技巧:要查
LIKE '%abc'?建一个反向字段REVERSE(col),然后查REVERSE(col) LIKE 'cba%'。
发散:从 LIKE 到相似度匹配
如果你觉得 LIKE 太“硬”,想在SQL里做模糊但智能的匹配(比如“张三”匹配“张三丰”、“张老师”),那么怎么实现?