138M文档,18分钟建完索引,查询快6.5倍——这不是Elasticsearch的发布会,是Postgres的扩展在干的事。
Tiger Data(TimescaleDB的团队)昨天把pg_textsearch 1.0甩了出来。一个原生BM25搜索引擎,直接长在Postgres的存储层上,不用外挂,不用同步,不用半夜爬起来修数据不一致。
用过Postgres内置ts_rank的人,都知道这套组合拳有多憋屈。语料库一涨,排名质量就塌。没有逆文档频率(IDF),"的"和"Postgres"权重一样。没有词频饱和,一篇把"数据库"复读50次的垃圾文,能碾压只提一次的技术深度文。更绝的是top-k查询——得把所有匹配行扫一遍才能算分。
于是大家被迫搞双系统:Postgres存数据,Elasticsearch或Typesense扛搜索。数据同步、集群运维、一致性对账,三件套加班套餐。
pg_textsearch想拆掉这套架构。纯C手写,基于Postgres原生存储层,BM25算法完整实现。建索引就一行:
CREATE INDEX ON articles USING bm25(content) WITH (text_config = 'english');
查询用<@>操作符返BM25分数。分数取负,所以Postgres默认升序ORDER BY直接出最相关结果。索引存在标准Postgres页里,走缓冲缓存,进WAL日志,pg_dump能备份,流复制能同步——和正常表一个待遇。
从内存玩具到生产级:5个月的重写
2024年10月的预览版还像个Demo:倒排索引全放共享内存,重启重建。180+提交之后,架构彻底换血。
磁盘化分段结构替换了内存-only设计。Block-Max WAND算法加WAND优化,让top-k查询不用全表扫。倒排列表压缩用SIMD加速解码,索引体积砍了41%。并行建索引,138M文档17分多钟跑完。
性能数字和ParadeDB/Tantivy正面刚:2-4词查询快2.4到6.5倍,并发吞吐高8.7倍。这是Tiger Data自己跑的分,但他们也老实交代了ParadeDB更快场景——长查询、复杂布尔,Tantivy的优化更成熟。
「我们选择在Postgres页内实现,而不是外部存储,」团队在技术博客里写,「这意味着你得到的是事务一致性、崩溃恢复、备份工具链的完整继承,代价是某些极端场景下不如专用引擎灵活。」
BM25为什么难搞:三个数学细节
ts_rank和BM25的差距,本质是信息检索理论的代差。
逆文档频率(IDF)解决的是"这个词有多特别"。在1000万文档里出现100次的词,比出现500万次的词,权重该高两个数量级。ts_rank没有这茬。
词频饱和解决的是"复读机问题"。BM25的公式里,词频增长对分数的贡献是边际递减的——第2次提到"数据库"加分多,第50次几乎不加。ts_rank线性累加,催生SEO垃圾文。
字段长度归一化解决的是"篇幅偏见"。200字的短文档和2万字的百科全书,同样提到3次关键词,前者应该更聚焦。BM25算这个,ts_rank不算。
pg_textsearch把这三件套全塞进Postgres的索引AM(访问方法)接口。<@>操作符背后,是完整的BM25公式计算,包括可调节的k1和b参数。
架构解剖:为什么不搞外部存储
ParadeDB和Tantivy的路子是:用Rust写高性能引擎,通过Postgres的FDW(外部数据包装器)或自定义协议桥接。查询时要跨进程通信,数据要两份存储。
pg_textsearch赌的是另一条路:完全内嵌。
索引结构用Postgres的页(8KB默认)存储,分段(segment)管理。每个段是独立的倒排索引单元,支持后台合并。WAL日志记录所有变更,崩溃恢复走标准流程。缓冲缓存自动管理热数据,不用自己搞内存池。
代价是代码复杂度。Postgres的AM接口设计于90年代,给B-tree用的。倒排索引的随机访问模式、压缩编码、SIMD解码,都要在接口缝隙里塞进去。Tiger Data团队重写了五个月的存储层,才把预览版的内存结构改成磁盘持久化。
Block-Max WAND是查询层的关键优化。传统BM25要对所有匹配文档算分排序,WAND用块级上界(block-level upper bound)剪掉不可能进top-k的分支。138M文档的语料库,查"database ranking"两个词,可能只扫几千个块就停。
谁该用,谁再等等
现阶段的限制,团队列得清楚。
短语查询和邻近搜索还没做,tsquery的<->操作符不支持。多字段加权(标题权重2倍,正文权重1倍)需要建多个索引手动合并。实时更新是行级触发器实现,高频写入场景有开销。最要命的可能是:还没和Postgres的并行查询执行器深度整合,某些plan会选错。
但场景对口的人,现在就能上。内容站点、文档知识库、电商商品搜索——数据已经在Postgres里,查询模式是2-4个关键词的 relevance ranking,不想养第二个集群。
Tiger Cloud客户已经能用托管版。开源版在GitHub,Apache 2.0协议,自己编译安装。
一个细节:团队特意测了pg_dump和pg_restore的兼容性。138M文档的索引,备份恢复走标准流程,不需要额外工具。这对运维来说是真金白银的省心——不用写自定义备份脚本,不用教新人"搜索集群的恢复流程不一样"。
Postgres生态的搜索方案,现在有三条路线并行。Elasticsearch侧car是成熟但沉重的老大哥。ParadeDB是性能激进的外部引擎派。pg_textsearch押的是"原生内嵌"——牺牲部分极限性能,换架构简洁和操作统一。
你的数据,现在有几份拷贝在跑?
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.