莱客AI商学院/文章/千万向量以内,用 Postgres 就够了
深度文章免费

千万向量以内,用 Postgres 就够了

「买一个向量数据库」这个采购动作,在多数中小企业的规模上已经不必要——真正的瓶颈也不是查询快慢,是建索引时的那块内存

AI 效率专家 · 商业研究院2026-03-17预计 8 分钟
千万向量以内,用 Postgres 就够了 封面

文章目录

共 4 节
01一、先别买:四个问题,答完再决定02二、pgvector 的两条硬边界:2000 维,和那条 NOTICE03三、三张价目表并排,和一个你自己能算的月账04四、先在现有库上试:五步顺序,以及什么时候这套不成立

一份采购申请上写着「向量数据库」,金额一栏填了个数,用途一栏写着"知识库检索"。批之前先问一句:你要存多少条向量?

如果答案是几十万到几百万条,甚至一千万条,那这份申请多半可以先不批——不是因为那些产品不好,是因为你手上很可能已经有一个能干这件事的东西了,而它叫 Postgres。

先把边界摆出来,免得后面被当成一句口号:这篇文章讲的是千万条以内这个区间。超过这个量级是另一回事,第四节会讲清楚在哪一步失效。还有一件必须先承认的事:千万级这个规模,没有权威的公开 benchmark。 在公开可查的范围内,唯一被广泛使用的中立第三方是 ANN-Benchmarks(维护者为 Martin Aumueller、Erik Bernhardsson、Alec Faitfull),它的方法论是把「Recall(所有查询平均找回的真实最邻近点比例)」对「Queries per second」画在一张图上,覆盖 4 种距离、9 个数据集、38 个以上算法,pgvector 也在列——但它的数据集规模都很小,SIFT 是 100 万条,GloVe 是 118 万条。用一份百万级的测试去证明千万级的结论,这一步在方法上是不成立的。 所以本文只拿官方文档里写死的边界说事。

一、先别买:四个问题,答完再决定

这四个问题的顺序不能换。答到任何一问答不上来,就先停在那一问,别往下走。

第 1 问:你要存多少条向量?

这个数决定了后面所有的判断,而且多数人报不出来。报不出来的时候不要估,去数——数你打算喂进去的文档数,乘以你的分块策略下每份文档大概切成几块。这个数拿不到,后面三问都是空谈。

第 2 问:每条向量多少维?超过 2000 了吗?

这一问是分水岭,理由在第二节。

第 3 问:你手上的那套系统,本来就是 Postgres 吗?

如果业务库已经是 Postgres,那这件事的增量成本可能只是装一个扩展。如果不是,那要多算一笔迁移或新建的账,结论会变。

第 4 问:你能接受"建索引那一段很慢"吗?

注意问的不是查询快慢,是建索引。这一问是全文最容易被跳过、也最容易在上线当天翻车的一问,同样放在第二节讲。

我的建议是把这四个答案写在同一张纸上,一张纸装不下就说明还没想清楚。

二、pgvector 的两条硬边界:2000 维,和那条 NOTICE

pgvector 是给 Postgres 加向量能力的扩展。要用它,先得知道它自己在 README 里写死的两条边界——这两条不是谁的评测,是官方文档的原话。

第一条边界:存得下的维度,和建得了索引的维度,不是同一个数。

README 写的是:向量「Vectors can have up to 16,000 dimensions」,半精度向量同样是 16,000 维,bit 类型「up to 64,000 dimensions」。

但索引那一节写的是另一组数:HNSW 与 IVFFlat 一致,vector「up to 2,000 dimensions」,halfvec「up to 4,000 dimensions」,bit「up to 64,000 dimensions」。

16,000 与 2,000 之间差了 8 倍——这一步是我按 README 给的两个数字自己算的除法,口径就是这两句原文。这个落差的实际含义是:你可以把一条 3072 维的向量原样存进去,但你建不了索引,查询会退化成全表扫。FAQ 里给的绕法也写在 README 上:「You can use half-precision vectors or half-precision indexing to index up to 4,000 dimensions or binary quantization to index up to 64,000 dimensions.」也就是说,超过 2000 维想要索引,路径是降精度或者二值量化,不是原样硬上。

所以第一问里那个"每条多少维"必须在采购之前拿到。这是一条真短板,得摆在明处:MongoDB Atlas Vector Search 的官方文档写的维度上限是 8192,比 pgvector 的索引上限高出一截。如果你的模型输出维度就是很高、又不接受降精度,那这一条足以让结论反过来。

第二条边界:真正的瓶颈是建索引时的内存,不是查询速度。

README 里有两句话必须原样读一遍。第一句:「Indexes build significantly faster when the graph fits into `maintenance_work_mem`」。第二句是官方给出的 NOTICE 原文:「hnsw graph no longer fits into maintenance_work_mem after 100000 tuples」。

请注意那个数:100000。十万条。 而你打算存的是一千万条——是这个数的 100 倍(这一步除法同样是我自己算的)。这句 NOTICE 不是说十万条就不能用了,它是在告诉你:图装不进那块内存之后,构建过程会显著变慢。README 紧接着还给了一条相反方向的警告:「Do not set `maintenance_work_mem` so high that it exhausts the memory on the server」——你不能靠无脑调大它来解决。

两条读完,第 4 问的分量就出来了:在千万这个量级上,你会遇到的第一堵墙不在查询侧,在建索引那几个小时。

采购向量库时大家都在比查询快慢,而在千万级以内,先把你拦住的通常是建一次索引要多久,以及那台机器的内存够不够。

同一份 README 还写了两种索引的取舍原文:「An HNSW index creates a multilayer graph. It has better query performance than IVFFlat (in terms of speed-recall tradeoff), but has slower build times and uses more memory.」——查询更快、构建更慢、更吃内存,这句是官方自己写的,不用去别处找评测。

IVFFlat 这一侧还有一个更具体的坑,是把两份官方文档并排放才看得见的。pgvector README 给的 lists 参数建议是:100 万行以内用 `rows / 1000`,超过 100 万行用 `sqrt(rows)`。而阿里云 RDS PostgreSQL 的官方中文文档写着:「当 lists 参数值超过 2000 时,会直接报错」。

把这两句放在一起算一次:一千万行取平方根,约等于 3162,大于 2000。也就是说,如果你在阿里云 RDS PostgreSQL 上照着 pgvector 官方公式给一千万行配 IVFFlat 的 lists,会撞上那条报错。这一步的推导是我把两份文档并排比对得出的,不是任何一方的原话,落地之前请以你所用实例的实测为准。 但它足以说明一件事:官方通用建议和你所在云上的实现限制,可能不是同一件事,采购之前要各看一遍。

云上的可用性也要先确认,省得批完申请才发现装不上:阿里云 RDS PostgreSQL 要求实例大版本 PostgreSQL 14 或以上、内核小版本 20230430 或以上;AWS 的版本表上,Aurora 侧停在 0.8.1,RDS 非 Aurora 侧到 0.8.2;腾讯云的插件列表里没有叫 pgvector 的条目,叫 `vector`,v13 到 v18 为 0.8.2,另有一个 `vectorscale` 插件为 0.9.0。pgvector 自身 0.8.1 发布于 2025 年 9 月 4 日,0.8.2 发布于 2026 年 2 月 25 日;它不使用 GitHub Releases,所以别去找"最新 release"这个说法。

至于容量天花板,README 只给了一句:「A non-partitioned table has a limit of 32 TB by default in Postgres.」——注意它给的是表的容量上限,不是"支持多少亿向量"。README 里没有任何"支持 N 亿向量"的官方数字,谁给你这个数,都得先问出处。

三、三张价目表并排,和一个你自己能算的月账

先说明口径:以下均为各家公开定价页数据,页面未标注发布日期,且多数带「from」「起」字样。这一节只用来做量级对照,不是报价单。

专用向量库这一侧:

  • →Pinecone:Starter 免费档 2 GB 存储;Builder 档「$20/month flat」;Standard 档「$50/month min. usage」,细则原文是「You'll be charged a minimum of $50/month. Once your usage exceeds this amount, you'll pay as you go.」;Enterprise 档「$500/month min. usage」。存储单价 $0.33/GB/mo。
  • →Weaviate Cloud:Free 档 $0/mo(100,000 objects / 1 GB memory / 10 GB disk / 1 collection);Flex 档「$45 /mo」起;Premium 档 $400/mo 起。向量维度单价「from $0.00465 / 1M」。SLA 三档为尽力而为、99.5%、99.9–99.95%。
  • →Qdrant Cloud:Free Tier 是单节点集群,规格 0.5 vCPU / 1GB RAM / 4 GB Disk;Standard Tier 按用量计费、99.5% SLA;Premium Tier 标的是「Minimum spend required」,具体金额未公开。

托管 Postgres 这一侧:

  • →Supabase:Free「$0/month」;Pro「from $25/month」,含「8 GB disk size per project included, then $0.125 per GB」和「$10/month in compute credits, which covers one Micro instance」;Team「from $599/month」。
  • →Neon:Free $0;Launch 与 Scale 两档都是「$0.35/GB-month」的存储费加一项按 CU-hour 计的计算费,两档的 CU-hour 单价不同。

把三个入门档并排放:Pinecone Builder $20/月 flat、Supabase Pro 从 $25/月起、Weaviate Flex 从 $45/月起。 这个对照说明的事情很朴素——在入门档这一层,专用库并不比托管 Postgres 贵到另一个数量级,所以"省钱"不该是你选 Postgres 的第一理由。 真正的理由是第四节要讲的那条:少一套要维护的东西。

下面这笔账你可以自己填。

拿 Weaviate 那个按维度计费的单价算一遍,因为它是三家里唯一能被外行当场算出来的。假设你有 1000 万条向量,每条 1536 维:

1000 万 × 1536 = 153.6 亿个维度 = 15,360 百万维度。按「from $0.00465 / 1M」计:15,360 × 0.00465 ≈ $71.4 / 月。

这一步是我按其公开单价自己算的,口径必须说清三点:第一,它只算了向量维度这一项,没算存储那 $0.12/GiB 起的部分;第二,单价写的是「from」,即起价,实际可能更高;第三,它没有把 Flex 档 $45/月起这个门槛叠进去。所以这个数不是账单,是一个让你有量级感的演算——把它跟你自己那台机器的月成本放在一起看,就够做决定了。

再给一份历史材料,用来说明"曾经有人这么测过",但它三条限制必须一起写出来。Supabase 在 2023 年 10 月 10 日发过一份 pgvector 与 Pinecone 的对比:数据集是「dbpedia dataset of 1,000,000 OpenAI embeddings (1536 dimensions)」;pgvector 侧用的是「single Supabase 2XL instance approximating ~410$/month(8-core ARM CPU and 32 GB RAM)」,Pinecone 侧扩到约 $480/月;在 0.98 accuracy 下,pgvector 比 Pinecone s1 pods「1185% more queries per second」。

三条限制:其一,这是 Supabase 自测,同文自陈立场「At Supabase, we believe that a combination of Postgres and pgvector serves as a better alternative to single-purpose databases like Pinecone.」,利益相关;其二,距 2026 年 3 月已过去两年多,双方产品都变过;其三,规模只有 100 万条,不是本文讨论的千万级。 那个 1185% 只能当"两年前有人在百万级上得到过这个结果",绝不能当成你会拿到的结果。

一份自测、两年前、一百万条——三个限制里少写一个,这份数据就从参考变成了误导。看到漂亮数字先找这三样,比看数字本身重要。

四、先在现有库上试:五步顺序,以及什么时候这套不成立

处方是五步,顺序不能换。步骤里的时长与阈值是本文给出的执行建议,不是任何文档的结论。

第 1 步。在你已有的那套 Postgres 上装扩展,先不迁移任何数据。 装完确认版本能对上你所在云的支持范围(阿里云要 PG14 以上且内核小版本 20230430 以上)。这一步做不通,后面全部不用做。

第 2 步。只灌真实数据的十分之一,先跑通链路。 用你自己的文档,别用示例数据集——示例数据的维度和分布跟你的不一样,跑通了也说明不了什么。

第 3 步。灌到全量,然后专门给"建一次索引要多久"计一次时。 这一步是四问里第 4 问的答案落地。计时结果要记下来,因为它决定了你以后每次重建索引要占用多长的窗口。HNSW 与 IVFFlat 各建一次,比一比构建时长和查询表现——README 已经告诉你结论方向(HNSW 查得快、建得慢、更吃内存),你要的是在自己数据上的具体数。

第 4 步。把 `maintenance_work_mem` 调一次,再计一次时。 调的时候记住 README 那句反向警告,别调到把服务器内存耗尽。这一步做完,你对"扩容能买回多少速度"就有了自己的判断。

第 5 步。前四步都顺,就不用买了;某一步卡死,再拿着卡住的那一步去谈采购。 带着一个具体问题去谈,和带着一句"我要上向量库"去谈,拿到的方案完全不同。

接下来是代价,四条。

第一,索引维度 2000 这条上限是真短板。 前面已经和 MongoDB 的 8192 并排过。如果你的向量维度就是高、又不接受降精度或二值量化,这套方案在第 2 问就该停。

第二,`maintenance_work_mem` 调不好,建索引会非常慢。 这不是"稍慢",官方原话是索引在图能装进这块内存时「build significantly faster」。它意味着你需要一个懂这台机器内存状况的人,而不只是一个会写 SQL 的人。这个人的时间是这套方案真正的成本,不在任何一张价目表上。

第三,十亿级仍然是另一回事。 Milvus 官方自述写的是:「In 2022, Milvus supported billion-scale vectors, and in 2023, it scaled up to tens of billions with consistent stability」,以及 Milvus Distributed 部署在 Kubernetes 上、面向「billion-scale or even larger」场景。这是厂商自述,不是第三方验证,但它足以说明专用系统在那个量级上有它的位置。

第四,量化能省下的内存很可观,值得单独评估。 Elastic 公布的二值量化 BBQ,官方描述是「delivering ~95% memory reduction while maintaining high ranking quality」,并给了一个规模例子:1.38 亿条 × 1024 维不量化约需 535 GB,用 BBQ 约 19 GB。这是 Elastic 自测、利益相关,必须打上这个标签再看。 提它不是让你去换产品,是让你知道:如果内存是你的主要约束,这条路该进你的评估表。

最后是不适用的场景,三种。

第一种:向量条数已经过亿。 这套不成立,别硬撑。

第二种:你的团队里没有人能碰数据库参数。 那么"少维护一套东西"这个好处对你不存在——你只是把维护责任从供应商那儿挪到了一个没人接的位置上。这套只在你已经有人在维护那套 Postgres 的时候才划算;没人维护的话,托管的专用服务反而更便宜,因为那笔钱买的是"不用有人管"。

第三种:你其实还没有数据。 如果文档还没整理、分块策略还没定,那先做的不是选库,是把数据理干净。库选得再对,喂进去的是三个版本互相打架的文档,结果一样不能用。

三则公开公告可以当旁证读:IBM 于 2025 年 2 月 25 日宣布收购 DataStax,官方稿把 AstraDB 描述为提供「NoSQL and vector database capabilities」;Databricks 于 2025 年 5 月 14 日宣布收购 Neon,把它描述为「a developer-first, serverless Postgres company」;Redis 于 2025 年 4 月 8 日宣布推出原生向量类型 Vector Sets。把向量能力做进通用数据库,是一条正在被多方投入的路线——这是从这三则公告读出的方向,不是谁的官方结论,也不构成对任何产品的推荐。

同一系列里另有一篇讲知识库不维护会发生什么的,和这一篇的第三种不适用场景接得上。