首页/数据/SQL 速查/LIKE 模糊匹配与转义

LIKE 模糊匹配与转义

百分号匹配任意长度、下划线匹配单个字符;前缀模式可走索引,前后都加百分号基本等于全表扫描,必要时用 ESCAPE 处理字面量。

SQL 速查数据更新于 2026-10-13

LIKE 是什么

LIKE 做模式匹配:百分号匹配任意长度字符串(包括零个字符),下划线匹配恰好一个字符。性能上有一条硬规则:只有前缀模式('abc%')能有效利用普通 B 树索引,前后都加百分号基本等同全表扫描。匹配字面量的百分号或下划线时必须转义,用 ESCAPE 子句显式指定转义符比依赖默认反斜杠更可控。需要包含关键词式的全文检索时,应该评估全文索引、pg_trgm 或独立搜索引擎,而不是反复扫大表。

基本信息

百分号 %匹配任意长度字符串,包含零个字符
下划线 _匹配恰好一个字符
ESCAPE 子句自定义转义符,如 LIKE '100!%' ESCAPE '!'
索引能力只有前缀模式能有效使用 B 树索引
大小写取决于排序规则:MySQL 默认不区分,PostgreSQL 区分
适用平台标准 SQL,MySQL 8.0 与 PostgreSQL 均支持

典型使用场景

  • 前缀搜索:按姓名首字母、编号前缀筛选,能走索引
  • 数据清洗:找出包含异常字符、多余空格、全角符号的记录
  • 粗粒度模糊查找:只知道片段时先定位范围
  • 黑名单匹配:查找内容里包含敏感词的记录,数据量大时改用全文索引
  • 格式粗校验:用模式检查编号是否符合基本形状,严格校验交给应用层
  • 排除测试数据:NOT LIKE '%test%' 过滤测试账号

示例

示例
SELECT * FROM users WHERE name LIKE 'Li%';        # 前缀匹配,能用索引
SELECT * FROM users WHERE name LIKE '%son';       # 后缀匹配,通常全表扫描
SELECT * FROM users WHERE code LIKE 'A_1';        # 下划线匹配一个字符

-- 匹配字面量百分号:用 ESCAPE 指定转义符
SELECT * FROM rates WHERE label LIKE '100!%' ESCAPE '!';

-- PostgreSQL 可用 ILIKE 做不区分大小写的匹配
SELECT * FROM users WHERE name ILIKE 'li%';

模式与索引能力

模式能否用索引说明
'abc%'可以前缀匹配,符合 B 树最左前缀
'%abc'不可以后缀匹配需要逐行比较
'%abc%'不可以典型全表扫描模式
'a_c'一般不可以下划线是通配符,前缀不固定
联合索引首列做前缀可以条件是前缀即可命中该索引
ESCAPE 后的字面量引号视写法而定转义符本身不影响索引选择
需要包含关键词式检索时,正确方向是全文索引(MySQL FULLTEXT、PostgreSQL tsvector)或外部搜索引擎,而不是给 LIKE '%x%' 加索引。
MySQL 中反斜杠默认是 LIKE 的转义符,匹配含反斜杠的内容容易出错;显式写 ESCAPE 更可控,也便于跨库迁移。
PostgreSQL 的 LIKE 区分大小写,MySQL 的默认排序规则不区分;跨库 SQL 若依赖大小写行为,应显式使用 ILIKE 或调整排序规则。
PostgreSQL 可以给 pg_trgm 扩展建 GIN 或 GiST 索引来加速 %abc% 这类包含匹配,代价是索引体积与写入开销都会上升。

使用要点

  • 把通配符放在末尾:'abc%' 能用索引,'%abc' 与 '%abc%' 不能
  • 能确定前缀就用前缀:把已知部分提到最左侧
  • 用户输入里的 % 和 _ 要转义,否则会被当作通配符放大匹配范围
  • 参数化查询里拼 LIKE 时用 CONCAT('%', ?, '%') 而不是手工拼字符串
  • 模糊匹配结果用于展示时要限制条数,避免一次返回大量数据
  • 清洗场景先备份:LIKE 命中的记录往往需要批量修数据
等值条件与前缀条件可以写在一起(code = 'A1' OR code LIKE 'A1%'),但 OR 会让两侧都难以优先走索引,能拆成两条查询合并就拆开。
转义符本身也要能被搜索:在 ESCAPE '!' 下匹配字面量感叹号要写 '!!',这类细节在批量清洗脚本里最容易出错,写完先用几条样例数据验证。

易错点

  • LIKE '%x%' 无法使用普通索引,数据量大时是典型慢查询源头
  • MySQL 中反斜杠默认是 LIKE 的转义符,匹配含反斜杠的内容容易出错,显式写 ESCAPE 更可控
  • 用户输入的百分号未转义,查询范围被意外放大,甚至匹配到全部记录
  • 依赖大小写不敏感的匹配,换到 PostgreSQL 后结果集变化
  • 用 LIKE 做大文本的包含检索,本应交给全文索引或搜索引擎,白白扫全表

数据来源与参考

  • MySQL 8.0 Reference Manual · Pattern Matching
  • PostgreSQL Documentation · LIKE
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌