首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >百倍性能提升背后:MySQL分析引擎的文本检索加速实践

百倍性能提升背后:MySQL分析引擎的文本检索加速实践

作者头像
腾讯云数据库 TencentDB
发布2025-10-31 11:25:20
发布2025-10-31 11:25:20
160
举报

腾讯的技术积累和专业现实业务中,基于关键字的搜索场景十分常见,提升文本检索性能是业务设计的关键。本文将介绍如何基于腾讯云 MySQL 分析引擎提升在全文检索场景下的查询性能。

全文检索是什么?

全文检索是一种能够快速在大量文本数据中查找包含特定关键词或短语的技术。支持基于内容的模糊搜索、相关性排序和语义分析,能够帮助用户从海量文本数据中快速定位所需信息。

在数据库领域中,全文检索解决了 like '%关键字%' 查询的性能瓶颈问题。传统的关系型数据库使用 like 进行模糊查询时,由于无法利用索引,需要对每行数据进行全表扫描,当数据量达到百万级别时,查询性能急剧下降。而全文检索通过建立倒排索引等机制,实现了亚秒级的检索响应。

对于一些中小型系统,在数据库中实现搜索功能,可以有效降低业务架构的复杂性,控制项目成本。

MySQL 分析引擎的全文检索性能

为了客观评估 MySQL 分析引擎的全文检索性能,我们设计了以下测试环境:

硬件配置

  • 测试服务器:M8.8XLARGE256 1 台

测试数据集

  • TPCH 数据集:
    • Lineitem 表,l_comment 字段
    • 6 亿行
    • 数据大小 73GB
    • 字段长度:
  • 亚马逊产品用户评论测试集:
    • amazon_reviews 表的review_body(评论内容)字段
    • 1.3 亿行
    • 数据大小 37GB
    • 字段长度:
TPCH 查询响应时间对比(单位:毫秒)

在MySQL 分析引擎中对lineitem表的l_comment字段建立全文索引,然后分别测试各家数据库的检索性能:

测试SQL:

无检出: select count(*) from lineitem where match(l_comment) against('apple' in natural language mode);

稀疏检出:select count(*) from lineitem where match(l_comment) against('fore' in natural language mode);

亚马逊产品用户评论数据集

在 MySQL 分析引擎中对amazon_reviews 表的review_body(评论内容)字段建立全文索引,然后分别测试各家数据库的检索性能:

测试SQL:

无检出: SELECT COUNT(*) FROM amazon_reviews WHERE match(review_body) against('abcxyz' in natural language mode);

稀疏检出:SELECT COUNT(*) FROM amazon_reviews WHERE match(review_body) against('abc' in natural language mode);

分析引擎全文检索的技术实现

通过上述测试,可以明显看到腾讯云 MySQL 分析引擎在全文检索场景下相比其他分析型数据库具备显著性能优势。那分析引擎是怎么实现的呢?

🚀 常用实现机制

目前业界实现全文检索能力主要是通过“基于辅助表”;“引用Lucene 库” 这两种模式去实现全文检索能力。

  • 其中以mysql、duckdb为代表的数据库全文索引普遍采用辅助表(Auxiliary Table)的实现方式 辅助表的实现方案主要将全文索引的数据以数据库辅助表的形式存储,这样可以利用数据表的查询能力来实现快速检索。如在mysql中当alter table建立全文索引后,会自动创建6张后缀为index的辅助表用于存储索引数据,其他表用于存储索引相关的信息。

如上图所示,以_index_1-6为后缀的被称为索引辅助表,表中存放倒排索引数据;例如表名为:ytt/fts_00000000000004c2_00000000000001ba_index_1,其中 ytt 代表数据库名,fts_ 开头和 _index_1 结尾表示辅助表,00000000000004c2 代表对应的表 ID 的十六进制值,00000000000001ba 代表加 fulltext 索引字段 ID 对应的十六进制值。其他表主要用于避免在全文索引字段频繁的删除操作导致对应的六张磁盘索引表成为热点。但因此可能带来的问题是数据可能被保存多份,没有及时的删除,占用额外的磁盘空间。

  • starrocks则采用的开源库CLucene库来实现分词,构建索引与检索能力。其中 Clucene 的实现也就是有序字典加倒排链的模式。 CLucene是Lucene项目中索引的C++实现库,提供了完整的查询引擎和索引引擎,部分语种文本分析引擎;CLucene实现主要采用FST(Finite State Transducer)存储分词后的关键词列表;索引数据则采用roaring bitmap存储。

采用开源库实现全文索引可以省略分词、构建倒排索引的繁琐细节,大大简化索引的构建,同时Clucene的检索性能也很高。但由于CLucene主要以文件的形式存放索引数据,同时各家数据库有自己的数据组织方式;数据库在管理自有的数据增删改时,需要同时管理索引数据的增删改等,会引入额外的管理成本。

🚀 分析引擎的实现机制与优化

分析引擎并没有选择以上两种模式,而是选择自研有序字典+倒排链的模式去实现全文检索。这样做的优点主要有:

  • 可以深度集成分析引擎自身的存储特点做定制化的优化,以提升效率。
  • 管理成本更低,无需管理外部开源库的索引数据更新逻辑。
  • 没有辅助表的多份冗余问题,磁盘空间占用更小。

索引原理

分析引擎的全文索引主要由关键字列表和倒排链数据构成。业界一般采用FST或有序字典存储关键词列表;倒排链中存储的是该单词出现的所有文档(document)的文档id,倒排链具有以下特点:

1. 倒排链中的文档行号是单调递增的

2. 倒排链中的文档行号具有稀疏性

倒排链采用roaring bitmap,一种高效的位图数据结构,特别适用于处理稀疏数据,roaring bitmap 将整个整数空间分为多个区间,每个区间固定大小为2^16(即65536),这对应于一个无符号16位整数的范围。对于每个区间,roaring bitmap用以下三种数据结构之一来存储数据:

1. Bitmap Container: 当区间内的数较多时(大约超过一定的阈值,通常是区间大小的1/4),使用一个64K大小的位图来表示哪些数字存在于该区间内。这是一个传统的位图,但只涵盖了一个小范围的数字。

2. Array Container: 当区间内的数较少时,使用一个数组来存储实际存在的数字,而不是使用位图。每个数字使用16位来表示,因此数组容器在存储稀疏数据时非常空间高效。

3. Run Container: 当区间内的数形成连续的范围时(即数字是连续的),使用RLE来存储连续数字的范围(起始数字和长度),这种方式在处理连续数字时非常节省空间。

关键词列表没有采用FST,而是采用有序字典,分析引擎的存储层采用列存文件,有序字典按行存储可以很好的易融入其中,同时列存文件支持添加稀疏索引,查询性能也很好。倒排链采用roaring bitmap存储文档的行号列表,与关键词列表的每一行一一对应,也存储在列存文件中。

索引构建

  • MySQL 分析引擎的存储层提供了索引框架,bloom filter、bitmap索引、全文索引都基于此框架实现。当数据从内存中刷新到磁盘的列存文件时或者从 redo 合并到列存基础数据时,就会同时调用索引的构建接口生成索引数据,按照行号写入列存文件中。
  • 对于全文索引的构建,首先将字段值采用指定的分词器进行分词,然后将获得的单词列表加入到有序词典中,同时获取单词列表对应的bitmap,然后将该文档id加入到bitmap中。
  • 对于全文索引的查询,首先在有序词典中检索关键词是否存在,然后获取对应的bitmap,bitmap中的文档id都是符合检索条件的;对于模糊匹配,在查询有序字典并且命中后,需要扫描关键词附近的其他关键词,检查是否满足条件,然后拉出一批倒排链,然后将这些倒排链求并集获得检索结果。

🚀 全文索引的表达式下推优化

虽然在实现上业界的全文检索方案有一定的区别。但实际上这几种实现的理论性能差距并不大。那分析引擎是如何做到与其他数据库更好的查询性能的呢?这主要源自于分析引擎存储层对全文检索的向量优化。

在分析引擎中,数据有三类:

  • 内存中的数据(MemRowSet)
  • 在磁盘中已经刷新并同步了全文索引的数据(DiskRowSet)
  • 还未合并的数据,可能在内存中,也可能在磁盘中。但未生成全文索引(Delta)。

目前在查询时,仅第二种也就是已经生成了全文索引的查询可以利用上全文索引的加速能力。而另外两种数据需要把数据扫描出来做后过滤。如图所示,可以看到通过索引扫描的数据,还需要再二次过滤,增加了消耗。

对于全文索引,DiskRowSet中通过索引扫描出的数据,重复过滤计算的成本却很大:

  • 对待匹配的文本进行分词,生成单词列表
  • 关键字尝试匹配单词列表中的单词

所以对于全文索引的查询场景,DiskRowSet中的数据从索引中扫描出来后,可以直接跳过Filter过滤逻辑;只有MemRowSet和Delta数据才需要走Filter,这样会节省大量的不必要的过滤计算。

综合来说,就是查询时可以对索引扫描出的数据不再进行重复过滤,可以显著提升全文索引计算性能。

分析引擎全文检索的技术优势

全文索引采用有序字典和roaring bitmap的实现方式,很好的融入存储框架,经过精细的优化使得全文索引查询性能优异。

原生集成优势

MySQL 分析引擎的全文检索功能作为数据库原生能力,避免了传统方案中需要维护多个系统(数据库 + 搜索引擎)的复杂性。数据同步延迟、一致性问题得到根本解决,简化了系统架构和运维负担。

列式存储优化

通过列式存储格式,分析引擎在全文检索时只需读取相关的词项列表,而非整行数据,大幅减少 I/O 操作。测试表明,在同等硬件条件下,I/O吞吐量提升3-5倍。。

智能查询优化

内置的代价优化器能够根据数据分布和查询模式,自动选择最优的执行计划。支持:

1. 自动索引选择:根据查询条件选择最合适的索引

2. 批量处理优化:对批量查询进行并行处理

3. 缓存智能管理:多层次缓存机制提升热点查询性能

资源隔离与稳定性

分析引擎通过MySQL从库的方式实现全文检索负载与事务处理的隔离,避免复杂查询影响在线业务。在高并发场景下,P99 延迟保持在 200ms 以内,稳定性显著优于传统方案。

未来展望与特点总结

MySQL 分析引擎通过创新的存储架构和查询优化技术,在全文检索场景下实现了百倍级别的性能提升。目前分析引擎 4.2506.1.0 版本已经具备此功能,并正式对外提供试用。

对于需要处理海量文本数据又希望保持系统简洁性的应用场景,MySQL 分析引擎提供了理想的解决方案。随着技术的持续演进,其在全文检索领域的优势将进一步扩大,为企业数字化转型提供强大支撑。✌️ 立即体验分析引擎,加速全文检索效率

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-10-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯云数据库 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • TPCH 查询响应时间对比(单位:毫秒)
  • 亚马逊产品用户评论数据集
  • 原生集成优势
  • 列式存储优化
  • 智能查询优化
  • 资源隔离与稳定性
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档