SaaS后台经常需要搜索客户名称、订单信息、商品描述、工单内容、用户留言和内部备注。很多开发者首先想到的是 LIKE '%关键词%',当数据量和搜索需求增加以后,又会考虑MySQL FULLTEXT,甚至直接引入Elasticsearch等专用搜索系统。
FULLTEXT到底适不适合SaaS后台,关键并不只是数据有多少,而是搜索什么、怎样搜索、需要多复杂的排序和分词,以及搜索结果是否必须具备很高的相关性。
MySQL FULLTEXT的核心优势,是可以针对文本建立全文索引,让数据库不必每次搜索都逐行扫描长文本。对于产品描述、文章、工单正文、用户留言等包含大量自然语言内容的字段,它通常比简单的 LIKE '%keyword%' 更适合。
但FULLTEXT并不是所有“模糊搜索”的替代品。
例如后台需要按照订单号、客户编号、手机号、状态码或者邮箱地址搜索,这些字段通常并不是自然语言文本。对于这种场景,普通B-Tree索引往往更加合适。
特别是类似订单号这样的结构化字段,如果查询条件是固定前缀,例如:
WHERE order_no LIKE '202609%'
这类查询在满足条件时可以利用B-Tree索引进行范围查找。而:
WHERE order_no LIKE '%202609%'
则是另一回事,因为通配符出现在开头,普通B-Tree通常无法直接利用索引完成这种任意位置的包含搜索。
因此,SaaS后台最好不要把所有搜索字段都塞进FULLTEXT。
多租户是另一个必须考虑的问题。假设一个SaaS系统有大量客户,表中存在 tenant_id,搜索通常类似:
SELECT id, title
FROM tickets
WHERE tenant_id = ?
AND MATCH(title, content) AGAINST(? IN NATURAL LANGUAGE MODE);
这里的 tenant_id 负责租户范围过滤,FULLTEXT负责文本检索。两者解决的是不同问题。
更重要的是,FULLTEXT索引本身并不会因为存在很多租户就自动实现租户隔离。真正的数据隔离仍然需要依靠应用层查询条件、数据库权限设计以及必要的数据访问控制。
对于超级租户,也就是某些客户的数据量远远超过普通租户的情况,还需要特别关注查询资源和数据分布。一个拥有数百万条记录的租户,与数千个只有几百条记录的小租户,其搜索负载完全不同。因此,不能简单按照“租户数量超过多少就必须分表”来设计。
FULLTEXT的搜索模式也需要理解。
MySQL常见的全文搜索模式包括自然语言模式和Boolean模式。自然语言模式更适合按照文本相关程度进行一般搜索,而Boolean模式提供了更加明确的查询控制,例如必须包含某个词、排除某个词或者使用通配符等。
Boolean模式并不是简单意义上的“精确匹配”。如果业务需要真正的精确字段匹配,通常仍然应该使用普通条件和B-Tree索引。
中文搜索则需要额外考虑分词问题。中文没有像英文那样天然通过空格划分单词,因此MySQL全文搜索的分词方式会直接影响搜索结果。InnoDB支持ngram parser,可以把文本按照指定粒度进行切分。对于中文搜索需求,这可能非常有用,但也会增加索引规模和查询成本,因此应该根据实际中文搜索样本进行测试,而不是默认开启以后就认为搜索质量一定会提高。
还有一个容易混淆的问题:FULLTEXT和普通B-Tree索引并不是简单的“二选一”。
一个工单后台可能同时需要:
WHERE tenant_id = ?
AND status = ?
AND created_at >= ?
这样的结构化筛选,以及:
MATCH(title, content) AGAINST(?)
这样的全文搜索。
前者可能需要普通B-Tree索引,后者使用FULLTEXT。实际查询通常还涉及排序、分页和返回字段,因此应该根据真实SQL和执行计划决定索引,而不是试图建立一个所谓“FULLTEXT+B-Tree复合索引”来解决所有问题。
分页同样值得注意。即使FULLTEXT已经快速找到大量匹配记录,如果应用一次返回大量结果,数据库仍然需要进行排序、过滤和结果处理。对于后台搜索页面,通常应该限制单页结果数量,并根据实际查询方式设计分页策略。
如果搜索结果需要按照相关性排序,MySQL可以提供基本的全文相关性排序能力。但它与专业搜索引擎提供的复杂相关性模型不是一回事。
例如用户搜索“订单异常”,MySQL能够根据全文匹配关系返回包含相关词语的记录,但它不会自动理解业务上的语义关系。它不知道“支付失败”“订单未完成”“扣款成功但订单仍显示待支付”在业务语义上可能属于同一类问题。
这正是MySQL FULLTEXT与Elasticsearch等专用搜索系统之间的重要区别。
如果业务只是让后台工作人员搜索工单、客户备注或者产品描述,关键词能够找到相关记录已经足够,那么直接使用MySQL FULLTEXT可以避免引入额外的搜索集群。
但如果业务开始要求复杂的中文分词、同义词、拼写处理、字段权重、复杂过滤、聚合、搜索建议、相关性调优以及大规模搜索并发,那么专用搜索系统的价值就会越来越明显。
另一个容易忽视的问题是FULLTEXT索引的维护成本。文本插入和更新时,全文索引也需要维护。因此,如果一张表的正文内容频繁修改,同时又存在大量搜索请求,FULLTEXT并不是完全免费的性能功能。
数据库磁盘空间、Buffer Pool、写入吞吐量以及查询并发都应该通过实际测试观察。不存在一个适用于所有MySQL服务器的固定公式,例如“FULLTEXT一定占原数据1.5倍”或者“百万条数据一定只能使用某种方案”。
真正可靠的判断方式,是建立真实的搜索数据集,使用实际业务查询进行压测,同时观察查询延迟、CPU、磁盘IO、内存、索引大小以及写入性能。
对于SaaS后台,可以把搜索需求大致分成三层。
第一层是结构化搜索,例如订单号、客户ID、邮箱、状态、时间范围。这类查询优先使用普通字段和B-Tree索引。
第二层是普通文本搜索,例如工单标题、产品描述、内部备注和文章内容。如果搜索逻辑不复杂,MySQL FULLTEXT通常已经可以满足需求。
第三层是复杂搜索,例如多字段权重、中文分词、同义词、搜索建议、复杂相关性排序、大规模全文检索和高并发搜索。这时候可以考虑将搜索能力独立到Elasticsearch或其他专用搜索系统。
需要注意的是,引入搜索引擎以后并不会让系统自动变得更简单。应用需要维护数据库与搜索索引之间的数据同步,还需要考虑消息延迟、重复消费、删除同步、索引重建以及搜索结果与主数据库之间的数据一致性。
因此,小型SaaS系统没有必要因为看到“全文搜索”三个字就立即部署Elasticsearch。多一个基础设施,就多一套监控、备份、升级、容量管理和故障处理工作。
MySQL FULLTEXT真正适合的场景,是搜索需求仍然属于数据库能够自然承担的范围:数据已经存在MySQL中,搜索主要围绕业务文本展开,对相关性和分词的要求没有复杂到需要独立搜索平台,而且团队希望减少基础设施数量。
当搜索逐渐成为产品的核心能力时,再把搜索服务独立出来通常更加合理。
最终判断FULLTEXT是否适合SaaS后台,不应该只看“100万条还是500万条数据”这样的数字,而应该看四件事:搜索字段是什么、查询模式是什么、结果质量要求有多高,以及数据库本身能否在实际负载下稳定完成搜索。
数据库搜索最怕的不是数据多,而是把完全不同的问题硬塞进同一种索引。结构化字段交给B-Tree,文本搜索交给FULLTEXT,真正复杂的搜索再交给专业搜索系统。架构做到这一层次,通常比提前堆上一套搜索集群更加务实。
MySQL FULLTEXT 是否适合 SaaS 后台搜索?实际使用时需要考虑什么
图片说明:示意图 图片来源:Public Domain(公有领域)
喜欢这篇报道?
使用下面的功能,方便以后继续阅读和分享 MNewsTV
关于文章收藏
收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。
删除收藏请进入「我的收藏」进行管理。
捐助(Paypal): https://www.paypal.me/observeccp 订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP