前言
在业务开发中,我们经常会遇到大文本字段的模糊查询场景:比如内容平台的文章检索、客服系统的工单搜索、电商平台的商品描述匹配等。很多开发者第一反应是使用LIKE '%关键词%'实现,但当数据量增长到十万级以上时,这类查询往往会出现明显的性能下降,甚至出现几十秒的超时,严重影响用户体验。
作为主流国产数据库之一,达梦数据库(DM)内置了成熟的全文检索组件,不需要依赖第三方中间件(如Elasticsearch),即可实现毫秒级的文本检索能力,完美替代传统LIKE模糊查询,同时降低架构复杂度。本文从实战角度出发,完整讲解达梦全文检索的优化方案、配置示例及落地踩坑指南。
LIKE模糊查询的性能痛点
我们先拆解LIKE模糊查询的性能问题根源:
- 索引失效问题:当LIKE查询以
%开头时,数据库无法使用普通B+树索引,只能执行全表扫描,逐行匹配文本内容,数据量越大耗时越长。 - 资源消耗高:全表扫描会占用大量CPU和IO资源,在并发场景下很容易把数据库资源打满,影响其他业务正常运行。
- 扩展性差:当数据量达到百万级以上时,LIKE查询的耗时会线性增长,没有优化空间,只能被迫引入外部检索组件,增加架构复杂度。
我们可以通过一组测试数据直观感受性能差距:
| 数据量 | 查询方式 | 平均耗时 | 相对性能 |
|---|---|---|---|
| 10万行 | LIKE ‘%优化%’ | 2.31s | 1倍 |
| 10万行 | 全文检索 | 0.018s | 128倍 |
| 100万行 | LIKE ‘%优化%’ | 18.72s | 1倍 |
| 100万行 | 全文检索 | 0.047s | 398倍 |
| 500万行 | LIKE ‘%优化%’ | 92.15s | 1倍 |
| 500万行 | 全文检索 | 0.11s | 837倍 |
当然,LIKE查询也不是完全没有适用场景:如果是前缀匹配(LIKE '关键词%'),依然可以用到普通索引,性能优于全文检索,适合短字符串的前缀匹配场景。对于中长文本的任意位置关键词匹配,全文检索是更优选择。
达梦全文检索核心原理
达梦全文检索的核心是倒排索引技术:
- 构建索引时,会对文本内容进行分词,将文本拆分为一个个独立的关键词,然后记录每个关键词出现在哪些文档的哪些位置。
- 查询时,直接根据关键词查找倒排索引,快速定位到包含关键词的文档,不需要遍历全表。
- 内置中文分词器,支持通用中文分词、自定义词库、停用词过滤等能力,满足不同领域的分词需求。
达梦全文检索的架构轻量化,和数据库内核深度集成,不需要额外部署服务,数据一致性有保证,同时支持事务,非常适合中小规模的文本检索场景,以及信创环境下的国产数据库替代方案。
实战优化步骤
第一步:环境准备与前置检查
首先确认你的达梦数据库版本和配置支持全文检索:
- 版本要求:DM8及以上版本均内置全文检索功能,DM7需要单独安装组件。
- 开启全文检索功能:
|
|
- 权限配置:给业务用户授予全文索引操作权限:
|
|
第二步:创建全文索引(两种常用方式)
根据业务场景选择合适的索引创建方式:
方式1:单字段实时同步索引
适合查询实时性要求高、文本更新频率低的场景,比如文章内容、商品详情:
|
|
方式2:多字段定时同步索引
如果需要同时匹配多个字段(比如标题+内容),且文本更新频率高,适合用定时同步策略,降低实时同步的性能开销:
|
|
小技巧:如果不需要自动同步,也可以选择手动同步,适合归档类静态数据:
CREATE FULLTEXT INDEX ... SYNC MANUAL;,手动同步执行:ALTER FULLTEXT INDEX idx_ft_article_content SYNC;
第三步:查询语法与优化技巧
常用查询语法
达梦全文检索使用CONTAINS函数实现查询,支持丰富的查询语法:
- 包含任意一个关键词:
|
|
- 包含所有关键词:
|
|
- 精确短语匹配:
|
|
- 按相关性排序:
|
|
查询优化技巧
很多人用全文检索还是慢,大多是查询写法不对,注意以下优化点:
- 避免返回大文本字段:查询时不要写
SELECT *,content字段通常很大,会严重拖慢返回速度,只返回需要的字段即可:
|
|
- 过滤条件前置:如果有其他带索引的过滤条件(比如时间、分类、状态),放在CONTAINS前面,先缩小数据范围再做全文检索,性能可以提升30%以上:
|
|
- 分页查询优化:不要在子查询里排序再分页,直接用LIMIT/OFFSET:
|
|
第四步:参数调优,进一步提升性能
1. 内存缓存优化
调整全文索引缓存大小,建议设置为服务器物理内存的10%-20%,大幅提升查询命中率:
|
|
2. 分词优化
如果是专业领域场景,内置分词器可能分词不准确,可以添加自定义词库:
- 找到达梦安装目录下的
/lexer/chinese/userdict.txt文件 - 每行添加一个自定义词汇,比如"达梦数据库"“全文检索"等专业术语
- 重建全文索引生效:
ALTER FULLTEXT INDEX idx_ft_article_content REBUILD;
3. 存储优化
将全文索引存储在高速SSD磁盘上,创建单独的表空间:
|
|
生产环境性能对比
我们在生产环境500万行文章表上做了压测,结果如下:
| 指标 | LIKE模糊查询 | 全文检索(优化后) |
|---|---|---|
| 平均查询耗时 | 92.15s | 0.11s |
| 峰值QPS | 0.01 | 9 |
| 平均CPU占用 | 97% | 24% |
| 平均IO占用 | 100% | 12% |
优化后,查询性能提升了800多倍,资源占用大幅下降,完全满足高并发场景的需求。
常见踩坑与解决方案
1. 全文索引不生效
排查步骤:
- 检查
ENABLE_FULLTEXT参数是否开启 - 检查索引状态:
SELECT STATUS FROM DBA_FULLTEXT_INDEXES WHERE INDEX_NAME = 'IDX_FT_ARTICLE_CONTENT';,返回VALID为正常 - 检查查询语法:CONTAINS函数的第二个参数是否正确,关键词有没有拼写错误
2. 索引同步卡顿
问题原因:写入频繁的场景使用SYNC ON COMMIT策略,每次提交都要同步索引,导致写入性能下降。
解决方案:
- 改为定时同步,比如每小时同步一次,或者在凌晨低峰期同步
- 重建索引时使用
ONLINE参数,避免锁表:ALTER FULLTEXT INDEX idx_ft_article_content REBUILD ONLINE;
3. 检索结果不全
问题原因:索引同步不及时,或者分词器没有识别到关键词。 解决方案:
- 手动执行索引同步:
ALTER FULLTEXT INDEX idx_ft_article_content SYNC; - 将缺失的关键词添加到自定义词库,重建索引
4. 特殊字符查询问题
如果需要查询包含特殊字符(比如+、-、&)的内容,需要用转义符\转义,或者用双引号包裹:
|
|
落地建议
- 索引规划:不要给所有文本字段都建全文索引,只给经常需要模糊查询的字段创建,减少存储和同步开销。
- 同步策略选择:静态归档数据用手动同步,更新少的业务数据用实时同步,更新频繁的业务数据用小时级定时同步。
- 监控配置:监控全文索引的同步延迟、查询耗时、缓存命中率,及时调整参数。
- 数据备份:全文索引会随普通数据一起备份,恢复时不需要额外操作,和普通索引一致。
通过以上优化步骤,我们完全可以在不引入外部检索组件的前提下,将大文本模糊查询的性能提升数百倍,解决LIKE查询带来的慢查询问题。达梦数据库的全文检索功能经过大量生产环境验证,稳定性和性能都满足业务需求,是信创场景下文本检索的最优选择。