文章审视 pg_vectorsearch 与 pgvector 的亿级向量测试,认为查询提速明显,但 49 分钟对 42 小时的建索引比较存在条件偏差。新扩展采用分区路由及压缩筛选,当前仍处于 alpha 阶段。
在一台配备 64 个 vCPU、512 GiB 内存的机器上,pgvector 为 1 亿条向量构建 HNSW 索引,耗时 42 小时。在同一台机器上,Timescale 新推出的 pg_vectorsearch 扩展只用了 49 分钟就建好了索引,查询耗时也只有前者的一半。
这些数字来自 Tiger Data(原 Timescale)于 2026 年 10 月 13 日发布的产品介绍文章。如果你在 Postgres 上跑 RAG,很难不被这个标题吸引。我仔细看了这篇文章、代码仓库、调优文档、基准测试工具的配置文件,以及 Hacker News 上的讨论,想弄清楚 pg_vectorsearch 对比 pgvector 的这些说法究竟有多扎实。先说结论:查询端的优势确实存在,而且很明显。但索引构建时间的比较条件有所倾斜,加上这个扩展还处于 alpha 阶段,目前不适合用于生产环境。
这个扩展新增了一种名为 PRISM(Partitioned Routing Index for Similarity Matching,用于相似性匹配的分区路由索引)的索引访问方法。README 说它“在概念上类似于 pgvector 的 IVFFlat”,这是理解它最直接的方式。它是一种分区索引:
最后一步解释了内存占用差异的主要来源。HNSW 要保持高速,就必须把一张庞大的图放在内存中;PRISM 只需在内存中保留一棵小树,其余部分通过扫描紧凑的倒排列表来处理。
它也能读取 pgvector 的类型。vec32 和 vec16 分别与 vector 和 halfvec 二进制兼容,因此你可以直接在现有表上创建 PRISM 索引:
CREATE EXTENSION pg_vectorsearch;
CREATE INDEX documents_embedding_prism
ON documents USING prism (embedding vec32_cosine_ops);
SET prism.nprobe = 40; -- 0 = auto, roughly 0.95 recall
所有数据均来自发布文章,延迟指标为 p50,召回率则以暴力搜索结果为基准,使用 recall@10 衡量。HNSW 使用的是 pgvector 的 16 位 halfvec。
HNSW 没能在 128 GiB 内存的机器上完成索引构建。他们把大机器上建好的索引迁移过去后,在 95% 召回率下,查询耗时超过了 1 秒,而且始终没能达到 99% 召回率。
他们实际上并没有在 2 GiB 内存的机器上尝试运行 HNSW。文章说,在那台机器上“实在没法尝试”,而表格中标注的是“未完成”。
标题中“用少 4 倍的内存,在 1 亿条向量上实现 6 ms 查询”,比较的是 128 GiB 机器上的 PRISM 与 512 GiB 机器上的 HNSW。我认为这个比较是公平的:两者都达到了 95% 召回率,而其中一台机器的成本只有另一台的四分之一。
先看 HNSW 的构建设置。Tiger Data 的基准测试工具 rekall 附带了一份 HNSW 配置文件 hnsw-m16.toml,其中设置了 m = 16 和 ef_construction = 200。而 pgvector 的默认 ef_construction 是 64。把它设为 200,可以构建质量更好的图,但也会大幅增加耗时。如果目标是 99% 召回率,这么做很合理,但它也会拉大索引构建时间的差距。文章没有说明公布的表格究竟使用了哪份配置,所以这里我依据的是仓库里的文件,而不是那次实际运行的配置。
文章也没有公布 maintenance_work_mem,而 pgvector 的 README 对这个参数为何重要说得很直接:一旦图无法继续完整放进 maintenance_work_mem,就会出现 hnsw graph no longer fits into maintenance_work_mem after 100000 tuples,随后构建“将花费明显更多的时间”。在一台 4 GiB 内存的机器上构建 2.05 GB 的 HNSW 索引,迟早会撞上这堵墙;为 100 万条向量建索引耗时 21.7 小时,就是撞墙后的表现。我不会把这称为 HNSW 的正常性能。122 ms 的查询耗时也是同一个道理:内存容纳堆表之后,已经放不下整个索引,因此查询需要读磁盘。
不过,这些数字并不虚假。“HNSW 一旦无法完整放进内存,性能就会垮下来”,恰恰就是 Tiger Data 想说明的问题。但如果你的 HNSW 索引本来就能完整放进 RAM,而且还有余量,那么那张 100 万条向量的测试表就不符合你的实际情况。
再看文章没有给出的内容:没有 QPS,没有 p99,没有并发测试(多客户端吞吐量测试被列为 GA 阶段的工作),没有带过滤条件的搜索,也没有 IVFFlat 的数据,尽管 README 把 PRISM 与 IVFFlat 作了比较;此外,文章也没有公布 embedding 的维度。带过滤条件的搜索,才是很多人在使用 pgvector 时真正头疼的地方,而 PRISM 目前的处理方式还比较基础:根据调优文档,执行器会在索引输出 top-k 结果之后,再应用 WHERE 子句;扫描时则根据预估的选择率增大 k。如果过滤条件与向量距离呈负相关,最终返回的行数仍然可能不足。文档建议针对过滤条件建立部分索引。支持 WHERE 过滤条件的流式搜索,已列入 GA 路线图。
在 HN 上,esafak 问了一个很自然的问题:“既然速度快,难道不该先把基准测试摆出来吗?请给出 qps 和精确率/召回率。”jascha_eng 回复说,基准测试就在文章里,而且测试套件已经开源。两人说得都没错。但这些毕竟还是厂商提供的数据,我目前还没看到 Tiger Data 之外的人公开发布复测结果。
根据发布文章,Tiger Data 在 2024 年推出的、采用 DiskANN 风格的索引 pgvectorscale,“将进入维护模式”。在 HN 上,Tiger Data 的 CTO mfreed 表示,pgvectorscale 的图中某些部分可能变得不可达,导致召回率下降;他们找不到解决办法,于是决定从头开始,改做分区索引。
也就是说,两年前告诉你“图索引就是答案”的厂商,现在又告诉你“图索引才是问题所在”。他们可能是对的。但他们也让你看到了:一个 Postgres 向量扩展,可以多快地从旗舰产品变成仅做维护的项目。
除此之外,还有一些实际障碍:
它仍处于 alpha 阶段。 README 写得很清楚:“用于测试,不适合生产环境”,并提醒你,在不同预发布版本之间升级时,可能必须删除并重新创建扩展。
它要求 PostgreSQL 18+。 pgvector 则支持 13+。
各大云厂商目前还不提供它。 在 HN 上,devy 指出,它尚未进入 Azure 或其他大型云平台的扩展允许列表,因此如果你使用这些平台,要么等待,要么自行部署 PG 18。另一位评论者提出同样的问题时,jascha_eng 的回答是:你可以迁移到 Tiger Cloud。
索引维护需要手动执行,而且被标记为实验性功能。 倒排列表会随着插入不断增长,并且“永远不会自行拆分”。CALL prism_rebalance('items_idx'); 可以原地拆分这些列表,但它只适用于使用 centroid_fastscan = off 构建的扁平、单层索引。默认的 CREATE INDEX 不会生成这种结构,因此对于按默认设置构建的索引,解决办法是执行完整的 REINDEX,重写整个索引。此外,再平衡操作替换掉的列表仍会留在磁盘上,直到下一次 REINDEX 才会清除。
不要在空表上建索引。 索引规模的规划依据是 CREATE INDEX 时的行数,所以应该先加载数据,再建索引。
使用高维向量时要小心。 调优文档说,在 8 KB 页面下,打包的 SIMD fastscan 布局始终可以容纳约 1900 维以内的向量,超过这个范围时,auto 会回退到较慢的布局。在 HN 上,devy 说“PRISM 的维度上限是 1968”;但我没在文档里找到明确的硬性上限。如果你使用 2048 维的 embedding(VoyageAI 就提供这种维度),请先测试,再决定是否采用。
如果 HNSW 的索引构建让你苦不堪言,先把构建配置调好,再考虑换扩展。下面的示例来自 pgvector 文档:
SET maintenance_work_mem = '8GB'; -- size it so the graph fits
SET max_parallel_maintenance_workers = 7; -- plus leader
CREATE INDEX ON items
USING hnsw ((embedding::halfvec(768)) halfvec_cosine_ops);
使用 halfvec:它能把索引大小减半,Tiger Data 的基准测试用的也是它。除非你已经通过测量确认需要更高的值,否则把 ef_construction 保持在 64。如果带过滤条件的查询返回行数不足,就开启 hnsw.iterative_scan(需要 pgvector 0.8.0+;当前版本为 v0.8.7)。
我的看法是:自 HNSW 进入 pgvector 以来,pg_vectorsearch 是 Postgres 向量搜索领域最值得关注的进展。VectorChord 走的也是“聚类加量化向量”这条路线。它自己的基准测试称,在 GIST 100 万条向量、960 维的数据集上,达到相同召回率时,其 QPS“可能是 pgvector 的两倍”。这同样是厂商提供的数据。不过,当两个独立团队都做出了分区索引,而且都跑赢了 HNSW,我倾向于相信这个方向是对的。
如果符合以下情况,可以现在就在副本或预发布环境中试用:
如果符合以下情况,就继续使用 pgvector HNSW:
WHERE tenant_id = ... 这类选择性很强的过滤条件,而且无法为每个租户单独建立部分索引。等到 GA 时再重新评估吧。按计划,届时应该会提供带过滤条件的流式搜索,以及自动、增量式再平衡。在那之前,“42 小时对 49 分钟”很适合放在演示幻灯片里,却不是迁移生产环境的好理由。
你现在用什么来做向量搜索:pgvector、VectorChord、pgvectorscale,还是 Qdrant 这样的专用向量数据库?如果你在自己的硬件上重新跑过 rekall,结果是否与这些数字一致?欢迎在评论区告诉我。
如需采取进一步措施,你可以考虑屏蔽此人,以及/或者举报滥用行为。