pgvector 基准测试为何会骗人

指南The New Stack2026年3月27日5 分钟阅读
pgvector 基准测试为何会骗人
pgvector 基准测试在 1 万条 128 维向量上表现完美,但到了 500 万条 1536 维向量的生产环境就问题频出。关键在于用代表实际工作负载的数据进行基准测试,并采用正确的索引、调优和 SQL 过滤策略。

pgvector 是一个开源 Postgres 扩展,让你能在关系型数据旁边存储和查询向量嵌入,使用你已有的表、事务和工具链。去年十月,Alex Jacobs 发表了一篇名为《反对 pgvector 的理由》的文章,在工程圈里流传甚广。他的观点是,那些鼓吹 pgvector 能直接替代专用向量数据库的博客文章,都忽略了在生产环境中大规模运行它的现实挑战(这里不展开,但文章确实值得一读)。

他说的没错。当时他描述的大部分情况对于原版 pgvector 都是准确的,这凸显了博客承诺与团队从本地 Postgres 实例转向生产工作负载时所遇到情况之间的差距。但过去几个月,pgvector 的故事已经进化了不少。

v0.5.0 引入的 HNSW 索引,相比 IVFFlat 基于聚类的方法,提升了召回率和查询一致性。增量索引构建能力更强了,在托管环境中运行 pgvector 的团队也开发出应对 Jacobs 描述的许多故障模式的操作模式。

这篇文章讲的是在你决定尝试 pgvector 后,如何成功使用它。Jacobs 的观点恰当地描述了团队把 pgvector 当作即插即用技术时会遇到什么,而接下来要说的就是如何避免那种结果。

笔记本 vs. 生产环境

pgvector 出现“演示能用,生产就崩”的模式,很可能是因为规模变化改变了哪些问题重要。在 1 万条 128 维向量上跑基准测试,结果很漂亮,查询和索引构建都很快。但这个基准测试几乎无法告诉你,同样的设置在 500 万条 1536 维向量下会如何运行。在那个规模下,索引本身就成了基础设施问题。

跨越数百万高维向量的 HNSW 索引,构建时所需的内存远多于查询时,而且这些内存来自你的生产数据库。索引构建可能持续数小时,过滤向量查询的查询规划器成本估算可能波动很大,而且任何部署(或故障转移)后,首批用户都要承受冷缓存惩罚,因为 ANN 算法需要时间进入状态。

“在 1 万条 128 维向量上跑基准测试,结果很漂亮……但这个基准测试几乎无法告诉你,同样的设置在 500 万条 1536 维向量下会如何运行。”

把这些看作有已知解决方案的工程问题,而不是障碍。没错,它们需要不同于标准关系型 SQL 的操作思维,而且可能只在工作负载达到一定规模时才显现。但措手不及的团队,往往是那些用非代表性规模数据做基准测试的。

先做基准测试再决定!

我坚信这是 pgvector 实施中最被忽视的一步。跳过它风险自负,因为它可能比其他任何失误带来更多痛苦。

社区基准测试能给你一个大致的预期,但在你实际应用中的性能会因向量维度、数据分布和数据集大小而异(通常差异显著)。在 1 万条 128 维向量上跑的基准测试,几乎无法告诉你你的系统在 500 万条 1536 维向量下会如何表现。

所以,在确定索引类型或数据库配置前,先用代表你实际数据集的数据跑自己的基准测试。在你预期达到的工作负载规模下,测量查询延迟、索引构建时间和搜索召回率。现在花一小时做基准测试,能让你免于日后更痛苦、更漫长的重构。

选择并调优索引策略

IVFFlat 与 HNSW 的选择取决于工作负载的匹配度。先说 IVFFlat。它构建更快,产生的索引更紧凑,是周期性批量更新或相对适中数据集的可靠选择。通过调整 lists(创建多少分区)和 probes(每次查询扫描多少分区)来控制速度/召回率的权衡。但关键要注意,IVFFlat 索引需要训练数据来创建有效的分区(这应该在数据加载后构建,而不是之前)。

然而,当你需要低查询延迟和高召回率来应对频繁的向量查询时,HNSW 胜出。它的图结构支持更快遍历,但索引创建时间更长,占用内存更多。这里的关键参数是 ef_search(算法在查询期间探索的广度)和 M(每个节点维护的连接数)。

无论你选哪个,都要针对你实际的查询模式和召回目标对这些参数进行基准测试。默认值和优化值之间的差距可能很大……然后,当你确定了有效的参数值后,把这些设置和索引定义一起存储起来。六个月后你的团队更新嵌入模型时,向量的维度和分布会变化,所以调优参数也需要相应调整。

为混合检索设计

在 Postgres 内运行向量搜索的一个未被充分利用的能力,是将其与结构化 SQL 操作结合。太多团队把 pgvector 当作一个碰巧在 Postgres 里的独立向量存储。这样做的人错失了显著的性能提升。

与其在整个数据集上运行向量相似性搜索,不如先用 SQL WHERE 子句缩小候选集。你可以按租户 ID、语言、内容类型或日期范围过滤。然后让 ANN 索引在这个缩小的集合上工作,而不是扫描整个表。特别是在多租户应用中,这种方法通常能将查询性能提升一个数量级。

你甚至可以更进一步,采用两阶段检索管道。先运行快速的 ANN 查询,获取前 N 个候选。然后用精确距离计算结合业务逻辑(新鲜度、用户权限、流行度加权等)对这些候选进行重排序。通过在 SQL 中进行重排序,你可以将整个操作保持在单个事务内。

这种混合方法是 pgvector 与 Postgres 集成带来最大回报的地方之一。虽然专用向量数据库擅长相似性搜索,但将其与任意 SQL 过滤器和事务性业务逻辑结合,通常需要编排层。但有了开源的 pgvector,你只需写 SQL。

智能分区,主动预热

你构建表的方式会影响向量查询性能,任何纯粹按数据量分区的本能都可能错过重点。

目标是按与你实际查询过滤器相关的字段分区。所以,如果你的应用总是按租户过滤,那就按租户分区。然后为每个分区构建向量索引,这样查询规划器可以在规划时修剪整个分区,意味着对于任何给定查询,向量索引只覆盖你总数据集的一小部分。

“任何纯粹按数据量分区的本能都可能错过重点。目标是按与你实际查询过滤器相关的字段分区。”

另一个在生产中让团队措手不及的是冷缓存性能。部署或故障转移后,支撑你向量索引的页面不会在内存中。首批访问系统的用户将承担从磁盘加载这些页面的成本,同时 ANN 算法遍历图。这时可以用像 pg_prewarm 这样的工具,让你在流量到来之前将热页面加载到共享缓冲区。你可以把这构建到部署流程中,这样从部署到服务的过渡就不会降低性能。

了解其边界

每个工具都有局限性,pgvector 也不例外。关键是理解它们。pgvector 正在积极开发中,版本兼容性是一个考虑因素,因为该工具支持某些 Postgres 版本但不支持其他。扩展需要你手动调优,就像应对任何 Postgres 性能挑战一样,没有自动调优层来处理内存分配、查询优化或索引配置。

对于需要在数千万向量上实现亚 20 毫秒延迟的应用,pgvector 可能是一个强大的起点,最终会升级到专用解决方案。从这里开始可以让你验证用例并理解查询模式(无需为单独的基础设施投入大量前期成本)。即使你超出了它的能力范围,你也会带着对你实际需求的更深入了解进行迁移。

成功团队的区别

一个贯穿始终的线索是,那些从 pgvector 中获得最大收益的团队,都像对待任何其他严肃的 Postgres 工作负载一样对待它。他们在做出重大架构决策前,会用代表性数据进行基准测试,并有意识地调优索引参数,而不是盲目接受默认值。他们还设计能充分利用完整 SQL 工具包的查询,并清楚了解 pgvector 在哪里适用,在哪里不适用。

如果你的团队已经在运行 Postgres 并且需要向量搜索,pgvector 从问题中移除了大量的架构复杂性。关键在于投入操作努力来良好运行它。Jacobs 说得对,博客文章跳过了困难的部分……但困难的部分通过正确的操作方法是可以管理的。

本文编译自 The reason your pgvector benchmark is lying to you,版权归原作者所有。

觉得有用?分享给更多人

获取每周 AI 工具精选

工具推荐、实战教程和生态洞察,每周更新。

相关文章

pgEdge 推出开源 MCP Server for Postgres,支持 AI 智能体通过模型上下文协议(MCP)而非传统 API 方式访问数据库。服务强调数据源无关性、完整模式自省和 token 优化,适用于 Claude Code、Cursor 等主流 AI 开发工具。

指南The New Stack·4月2日·4 分钟

Google 推出 Flex 和 Priority 两个新的推理层级,帮助开发者平衡成本与可靠性。Flex 是成本优化层级,适合后台任务,价格便宜一半;Priority 是最高保障层级,适合用户交互型应用。两者都通过同步接口调用,简化了架构管理。

指南·4月2日·3 分钟

评论