MySQL 全文检索性能优化:LIKE 查询拖慢主库?Canal 同步 ES + 增量实时更新!
公司的后台管理有一个搜索功能,搜订单备注里的关键词。刚开始数据量小,MySQL 的
LIKE '%keyword%'还能跑。后来订单涨到几百万条,一个模糊搜索要跑 8 秒。更倒霉的是,这个搜索请求直接打在主库上——索引走不了,全表扫描,CPU 飙到 90%,其他正常业务也跟着慢。
LIKE '%xxx%' 是数据库的噩梦。前导通配符导致索引完全失效,只能全表扫描。MySQL 虽然也有 FULLTEXT 索引,但中文分词烂、不支持复杂排序、而且仍然在主库上消耗资源。
今天聊聊怎么用 Canal 把 MySQL 的数据实时同步到 Elasticsearch,把搜索的活从主库彻底拆出来。
架构:主库只管写,搜索交给 ES
MySQL(主库) Elasticsearch
│ │
│ INSERT/UPDATE/DELETE │
├──── Canal 监听 binlog ──────────→├─ 增量同步
│ │
│ 业务读写 │ 全文搜索
│ (走主库) │ (走 ES)
Canal 伪装成 MySQL 的 Slave,订阅 binlog 的变更事件。任何 INSERT、UPDATE、DELETE 都会在毫秒级内被 Canal 捕获,然后转发给 ES。用户在后台搜东西的时候,直接走 ES 的搜索接口,主库完全不受影响。
Canal 怎么工作的
原理不复杂——MySQL 的主从复制所有从库都是一样的,Canal 只是假装自己是一个从库:
MySQL Master
│
├─ 写 binlog
│
├─ Slave(真正的从库)拉 binlog
│
└─ Canal(伪装从库)拉 binlog
│
├─ 解析 binlog 事件
├─ 过滤需要的表
└─ 转成 ES 文档 → 更新 ES
你的业务代码不用改一行——Canal 是旁路的,它不参与你的业务流程。你该 INSERT 还是 INSERT,Canal 在后台默默把数据搬到 ES。
增量同步的关键:顺序和去重
Canal 发过来的 binlog 事件是有序的——同一个事务内的操作保证顺序。但 Canal 到 ES 这条链路上,如果用了多线程消费,顺序可能被打乱。
解决办法:按主键哈希分区,同一个主键的操作始终发给同一个线程。 这样保证同一条记录的 UPDATE 一定在 INSERT 之后执行,DELETE 一定在 UPDATE 之后执行。
去重也很简单:ES 的文档 ID 用 MySQL 的主键。 同一条记录多次 UPDATE,ES 侧多次 Index 请求,后面的覆盖前面的,最终结果一致。
全量 + 增量两阶段同步
首次上线时需要把 MySQL 的历史数据全量同步到 ES。之后的增量由 Canal 接管。
上线流程:
1. 全量:SELECT * FROM table → 批量写入 ES
2. 记录全量完成时的 binlog 位点
3. 增量:Canal 从该位点开始消费
4. 全量和增量之间的窗口 → Canal 会补上
全量同步时注意别用单线程一条条写——几十万条数据写到明年去了。用 bulk API,每次 500~1000 条,吞吐量能到每秒几万条。
ES 侧要关注什么
Mapping 设计:需要搜索的字段用 text 类型(会分词),不需要搜索的用 keyword(精确匹配)。中文一定要用 ik_smart 分词器,不然搜"苹果"可能拆成"苹"和"果"。
写入优化:同步期间可以临时调大 refresh_interval 到 30s,减少 refresh 开销。全量同步完后恢复到默认 1s。
查询优化:ES 的 match 查询天然支持分词 + 排序 + 高亮。一个 LIKE '%keyword%' 要扫全表的查询,在 ES 里就是一次倒排索引查找,毫秒级。
总结
LIKE '%xxx%' 不是不能用——数据量小的时候没问题。但一旦数据量上来了,把搜索从主库拆出去是早晚的事。
三步走:
Canal 监听——伪装成 MySQL 从库,实时订阅 binlog。零侵入,原业务代码不动。
ES 接管搜索——模糊搜索、全文检索、复杂排序全交给 ES。主库不扫表,CPU 省下来给核心业务。
全量+增量——历史数据批量写入,增量 Canal 实时追。中间窗口自动补齐。
这套方案落地的成本主要在运维——多了一个 Canal 和一个 ES 集群。但收益是搜索性能从 8 秒降到 50 毫秒,主库 CPU 从 90% 降到正常水平。
有用的话转给还在主库上跑 LIKE '%xxx%' 的同事。
标题:MySQL 全文检索性能优化:LIKE 查询拖慢主库?Canal 同步 ES + 增量实时更新!
作者:jiangyi
地址:http://jiangyi.space/articles/2026/06/16/1781422978066.html
公众号:服务端技术精选
评论