公司的后台管理有一个搜索功能,搜订单备注里的关键词。刚开始数据量小,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、UPDAT....
SpringBoot + 全文检索 + ngram 分词 示例工程
项目简介 本项目是一个基于Spring Boot的中文模糊搜索示例工程,演示了如何使用MySQL的全文检索和ngram分词器来实现高性能、支持中文分词和错别字容错的搜索功能。 核心功能 全文检索 :使用MySQL的全文检索功能,提高搜索性能 ngram分词 :使用MySQL的ngram分词器,支持中文分词 错别字容错 :结合编辑距离算法,支持错别字搜索 缓存优化 :使用Redis缓存搜索结果,提高响应速度 异步事件 :使用Spring事件机制,处理商品更新时的缓存清除 测试数据 :提供测试数据生成功能,方便测试搜索性能 技术栈 Spring Boot 2.7.5 Spring Web Spring Data JPA Spring Data Redis MySQL 8.0 Lombok 工程结构 chinese-search-demo/ ├── src/ │ ├── main/ │ │ ├── java/com/example/demo/ │ │ │ ├── config/ # 配置类 │ │ │ ├── controller/ # 控制器 │ │ │ ├── dto/ # 数据....
SpringBoot + 全文检索 + ngram 分词:中文模糊搜索响应毫秒级,支持错别字容错
一、中文搜索的痛点 上周,一位做电商的朋友找我抱怨:他们的商品搜索功能太烂了。"用户搜索 'iPhone 13',结果只出来几个完全匹配的,"他说,"如果用户输入 'iphone13'、'苹果13'、'IPHONE 13',甚至打错字成 'ihpone 13',要么找不到结果,要么响应很慢。" 我打开他们的APP试了一下,确实如此: 搜索 "iPhone 13":找到10个结果,响应时间300ms 搜索 "iphone13":找到0个结果 搜索 "苹果13":找到0个结果 搜索 "ihpone 13":找到0个结果,响应时间800ms "我们用的是MySQL的LIKE查询,"朋友无奈地说,"'%关键词%'这种写法,数据量一大就很慢,而且不支持中文分词和错别字容错。"这样的搜索体验,用户怎么可能满意? 二、传统搜索方案的局限性 为了实现中文搜索,我们通常会使用以下方案: 1. MySQL LIKE查询 SELECT * FROM product WHERE name LIKE '%关键词%' OR description LIKE '%关键词%'; 这种方案的问题: 性能差:使用....
