针对用户呼声最高的全文搜索需求,Postgres 全文搜索扩展插件 TIN(Text INdex)正式推出通用版本(GA),面向所有 Postgres 和 Neki 数据库开放。

TIN 旨在提供快速、功能齐全且可靠的文本索引服务,支持布尔表达式、短语与跨度查询,术语的模糊、通配符及正则匹配,大小写与重音折叠,以及基于 BM25 评分的前 k 名查询和 COUNT(*) 统计。与其他现有方案不同,TIN 能在处理复杂 WHERE 子句、连接操作、持续更新、复制及事务可见性的同时,保持卓越性能。

应用场景与功能特性

TIN 适用于多种搜索场景:

  • 电商搜索:检索包含所有关键词的前十个产品,并按相关性排序。
  • 法律发现:返回包含任意关键词的所有文档,无需排名。
  • 标签统计:精确计算具有特定标签的照片数量。

系统支持在插入、更新和删除文档的同时进行查询,确保新提交的数据能立即被检索到。

性能基准测试

为评估性能,团队在 AWS i7i.8xlarge EC2 实例(8 vCPU, 32 GB RAM, NVMe 存储)上进行了基准测试。测试语料库采用 Stack Exchange 问答数据导出文件(85 GB,1.5 亿文档),生成 1,719 个合成查询轨迹。对比对象包括 ParadeDB v0.25.2、pg_textsearch v1.4.0 及 Postgres v18.6 内置 GIN 索引。

索引构建效率

在 32 GB RAM 限制下,仅 TIN 成功完成索引构建,耗时 8 分 10 秒,索引大小 50.7 GB。其他引擎因内存不足失败,需提升 RAM 至 64-128 GB 方可完成,耗时从 19 分钟到 2 小时不等。

查询性能表现

混合查询(前 10 名排名):在无并发写入情况下,TIN 的每秒查询量(QPS)是 ParadeDB 的 25 倍,p99 延迟低 26 倍。GIN 因内存溢出无法完成,pg_textsearch 仅支持析取搜索。

合取与短语查询:TIN 的 QPS 是 ParadeDB 的 10 倍、GIN 的 541 倍;p99 延迟分别低 6 倍和 1,356 倍。

带并发写入的析取查询:在每秒 1,000 次更新的负载下,TIN 的 QPS 是 pg_textsearch 的 36 倍、ParadeDB 的 57 倍。10 分钟内,TIN 完成 27 万次更新,而 pg_textsearch 仅完成 735 次,ParadeDB 完成 18.5 万次。

内存命中场景:当索引完全载入内存时,针对维基百科语料库的计数查询,TIN 的 QPS 达到 10,260,远超 ParadeDB(291)和 GIN(1.4)。

综合来看,TIN 的吞吐量至少比替代方案高 8 倍,且磁盘读取数据量显著更少,受并发写入影响极小。

技术架构解析

TIN 的高性能源于其独特的架构设计:

直接使用 ctid 作为文档标识

传统搜索引擎使用连续文档 ID,需额外映射回 Postgres 的 ctid(当前元组标识符),造成巨大开销。TIN 直接使用 48 位 ctid 作为文档 ID,避免了映射转换,实现 O(1) 物理位置查找。

两级位图编码与向量化

针对 ctid 的非连续性,TIN 采用页面级和偏移量级两级位图编码。利用 AVX-512/AVX2 指令集,对 256 位页面位图进行向量化 AND/OR 运算,大幅减少循环和分支指令。对于 COUNT(*) 查询,若页面无重叠,可直接通过元数据计算总和,跳过 postings 列表读取。

MVCC 与段合并优化

TIN 通过与 Postgres 可见性地图交集,高效处理 MVCC 可见性检查,避免不必要的堆访问。在段合并过程中,由于 ctid 全局唯一且含义不变,TIN 无需像传统系统那样重新编号和压缩数据,只需转移位图所有权,极大降低了写放大和 I/O 成本。

凭借上述优化,TIN 在各基准测试中均展现出显著的性能优势,为 Postgres 用户提供了高效的全文搜索解决方案。