LIKE '%suffix' 可查以特定字符结尾的数据,但因前导通配符导致无法使用B-Tree索引,常引发全表扫描;需通过倒序索引、TRIM预处理、转义特殊字符及避免逻辑歧义等方式优化。

LIKE '%suffix' 能查到以特定字符结尾的数据,但性能可能极差
直接写 WHERE column LIKE '%son' 确实能命中所有以 son 结尾的值(如 Johnson、Wilson),但数据库无法利用 B-Tree 索引加速——因为通配符在开头,优化器只能全表扫描。
常见错误现象:EXPLAIN 显示 type: ALL,查询耗时随数据量线性增长,百万行表可能秒级变数秒。
- 若字段有索引且业务允许,优先改用函数索引或倒序存储(如 MySQL 中建
REVERSE(column)的索引,再查REVERSE(column) LIKE 'nos%') - PostgreSQL 可直接用
column LIKE '%son'配合pg_trgm扩展加 GIN 索引 - SQL Server 2016+ 支持列存储索引对
LIKE '%x'有一定加速,但不如前导匹配稳定
中文、空格、不可见字符会让 '%suffix' 匹配失败
LIKE '%报告' 查不到值为 年度报告 (末尾带空格)的记录,因为 SQL Server 和 PostgreSQL 默认把尾随空格视为无关,但匹配时仍要求字面一致;而 MySQL 在 LIKE 中会忽略尾随空格,行为不统一。
使用场景:从日志表查 status LIKE '%ERROR',结果漏掉 'CRITICAL ERROR ' 这类带空格或制表符的值。
- 查前先
TRIM()或RTRIM():例如WHERE RTRIM(column) LIKE '%ERROR' - 确认字段实际内容:用
SELECT column, LEN(column), DATALENGTH(column)(SQL Server)对比长度差异 - 避免依赖隐式截断,尤其跨数据库迁移时,MySQL 5.7 与 8.0 对空白处理也不同
特殊字符如 % _ [ ] ^ 必须转义,否则被当成通配符解析
想查真实包含百分号的字符串,比如版本号 v2.1%beta,写 LIKE '%v2.1%beta%' 会误匹配 v2.1abcdbeta——中间那个 % 被当成了通配符。
正确做法是显式声明转义符,且注意不同数据库默认行为不同:
- SQL Server / PostgreSQL:用
ESCAPE '\',写成LIKE '%v2.1\%beta%' ESCAPE '\' - MySQL 默认不认反斜杠转义(除非
sql_mode含NO_BACKSLASH_ESCAPES),更稳妥的是换转义符,如LIKE '%v2.1|%%beta%' ESCAPE '|' - 方括号
[和尖号^在 SQL Server 支持字符集语法,但在 MySQL 中无意义,混用会导致语法错误
多个条件组合时,'%suffix' 容易引发逻辑歧义
写 WHERE name LIKE '%son' AND name LIKE '%er' 是查同时以 son 结尾、又以 er 结尾的字符串——这永远为假。真正想查的是“包含 son 且包含 er”,应改为 LIKE '%son%' AND LIKE '%er%'。
容易踩的坑:
- 误把后缀匹配当子串匹配,尤其在拼接动态 SQL 时,用户输入
son被套进'%' + @input + '%'还是'%' + @input容易混淆 - 用
OR连接多个LIKE '%x'时,执行计划可能放弃索引,即使其中某个条件本可走索引 - 参数化查询中,传入的值若含通配符(如用户搜
100%),必须提前转义,不能依赖前端过滤
最常被忽略的一点:后缀匹配本身不校验字符边界。查 LIKE '%cat' 会命中 scat、concat、education(因 cat 出现在词中),真要匹配单词结尾需结合空格或正则,LIKE 做不到。

















