后缀匹配 like '%keyword' 一定走全表扫描,因b+树索引仅支持左前缀匹配;唯一纯mysql解法是字符串反转+单独建索引,需同步维护反转列、在反转列建索引、查询时对关键词反转且用前缀匹配。

后缀匹配 LIKE '%keyword' 一定走全表扫描,没法绕开——这不是写法问题,是 B+ 树索引结构决定的硬限制。唯一实用、可控、纯 MySQL 的解法,就是字符串反转 + 单独建索引。
为什么 LIKE '%keyword' 永远不走索引
B+ 树索引按字典序从左到右排序,只支持“从开头匹配”。LIKE '%keyword' 要求定位末尾字符,优化器根本找不到扫描起点,只能放弃索引,退化为 type: ALL。哪怕字段上已有 INDEX idx_name (name),执行 EXPLAIN SELECT * FROM t WHERE name LIKE '%abc',key 列也一定是 NULL。
怎么建反转列并让查询真正走索引
核心是把“后缀问题”转成“前缀问题”,但必须严格对齐存储与查询逻辑:
Word报告自动生成神器。自动生成专业Word文档报告,支持模板填充、目录生成、表格/图表插入、页眉页脚、多级标题、样式主题、批量邮件合并。当用户需要生成Word报告、创建合同文档、批量生成通知/证书、填充Word模板、制作商业计划书时触发。
- 新增列存反转值:
ALTER TABLE users ADD COLUMN email_reversed VARCHAR(255) - 用触发器自动维护(推荐):
BEFORE INSERT/UPDATE中写SET NEW.email_reversed = REVERSE(NEW.email),避免应用层漏更新 - 索引必须建在反转列上:
CREATE INDEX idx_email_rev ON users(email_reversed);建在原字段email上完全无效 - 查询时,搜索词也要反转,且去掉左侧
%:WHERE email_reversed LIKE 'erriep%'(不是'%erriep',更不能写REVERSE(email) LIKE '%erriep')
常见翻车点:反转了但还是慢
线上最常出错的不是不会建,而是细节错位:
- 查询条件写成
email_reversed LIKE '%erriep'—— 又变回后缀匹配,索引失效 - 在
WHERE子句里对列用函数:WHERE REVERSE(email) LIKE 'erriep%'—— 函数作用于列,无法命中索引 - 大小写不统一:
REVERSE('Pierre')是'erriep',REVERSE('pierre')是'erriep',但若排序规则是utf8mb4_0900_as_cs,两者不等价,查不到 - 反转列长度超长(如原始字段 500 字符),B+ 树索引深度增加,
range扫描实际性能下降明显
这个方案不适合什么场景
它轻量、不引入外部依赖,但边界清晰:
- 不支持中缀模糊:
LIKE '%abc%'无法通过单次反转解决 - 不处理中文分词:
REVERSE('张三')是'三张',搜“张”或“三”仍得全表扫 - 高并发写入下,触发器带来额外开销,且必须确保和主字段在同一事务中更新,否则数据不一致
真正难的不是加一列、建一个索引,而是所有环节——插入逻辑、查询写法、字符集配置、大小写策略——必须严丝合缝对齐,漏掉任意一环,索引就形同虚设。










