去年底一家做电商内容推荐的客户找过来,情况很典型:他们上了一套 RAG 用来做商品问答,PoC 阶段用少量样本测得 QPS 200、P95 80ms,觉得性能非常好,直接推到了生产。上线第一天流量还没起来一切正常,第三天做完全量数据灌入之后,QPS 掉到 30,P95 飙到 900ms,业务侧收到了一堆客诉。技术团队排查了两周,最后发现问题不在代码而在选型——PoC 时用的数据量是 5 万向量,生产是 320 万;PoC 时没做冷启动测试,生产上每次重启要 8 分钟才能恢复到稳态 QPS;PoC 时用的是默认 HNSW 参数,recall 只有 78%,业务侧不得不把 top_k 从 10 拉到 50 来补召回,QPS 又被打了个折。
这不是个例。我们过去做的 RAG 项目里,大约有 3 成的团队会把选型阶段的 benchmark 数字当成生产表现的承诺,然后在上线后被现实打脸。这篇文章不做选型对比——向量数据库怎么选那篇已经把 5 家产品的定位和规模分档讲清楚了。这篇只讲一件事:假设你已经在 Milvus、PGVector、Qdrant 里锁定了候选,如何用真实的生产口径把它们拉齐对比,避免上线后返工。
1. 为什么官方 benchmark 和你的生产环境差 3-5 倍
先说结论:官方 benchmark 上给出的 QPS、延时、recall 三个数字,在生产环境几乎不可能完全复现。我们统计了过去一年在企业侧的 12 个 RAG 项目,官方 benchmark 和生产实测 QPS 的平均比值是 3.7 倍——官方跑出来 500 QPS 的配置,生产上通常只能跑到 130 上下。造成这个漂移的原因有 3 个假设:
假设一:查询是纯读、无写入干扰。 官方 benchmark 通常是灌数据、建索引、查数据 3 个阶段隔离进行。生产环境是同时读写的:一边有增量数据在写入、一边有查询在读取。写入会消耗 CPU、抢占 IO、破坏索引的稳态结构,Milvus 甚至会触发 compaction,短暂拖慢查询。这个假设漂移会让 QPS 打对折。
假设二:数据分布均匀、query 分布随机。 官方数据集(SIFT、GIST、DEEP1B)向量分布相对均匀,query 是从数据集里随机抽的。真实业务里,用户问题的语义分布是集中的(80% 的问题落在 20% 的语义簇里),embedding 空间会有明显的热点区,缓存命中率和 benchmark 完全不是一个量级。这个假设漂移会让 P99 尾延时至少放大 2 倍。
假设三:索引参数是最优配置。 官方跑分会为每份数据集调到最优的 HNSW M、ef、nprobe 参数。生产上大多数团队直接用默认参数,或者用 PoC 阶段的参数一路推到生产,recall 目标从 95% 掉到 85%,业务侧用扩大 top_k 来补,QPS 又被打折。
这 3 个假设漂移叠加下来,就是那个 3-5 倍的差距。想在生产上少踩坑,唯一的办法就是在选型阶段就用「生产口径」跑压测,而不是相信厂商 benchmark。
2. 3 家产品在同一口径下的核心对比
我们用一个统一的基准做了对比:数据集 300 万条 1024 维向量(来自客户脱敏的商品描述 embedding),机器 32 核 128G 内存 2TB NVMe SSD,recall 目标锁定 92%,读写比 9:1,并发压测持续 30 分钟取稳态。下面是 6 个维度的核心结果:
| 维度 | Milvus 2.4 (Standalone) | PGVector 0.7 (PG 16) | Qdrant 1.10 (单机) | 说明 |
|---|---|---|---|---|
| 稳态 QPS | 780 | 210 | 620 | 单实例、recall 92% 下的稳态数值 |
| P99 延时 | 45ms | 180ms | 55ms | 稳态下的 99 分位延时 |
| 冷启动时间 | 90s | 12s | 25s | 从进程启动到 QPS 稳定 |
| 索引重建时长 | 6 分钟 | 42 分钟 | 4 分钟 | 300 万向量、HNSW 索引 |
| 内存占用 | 14 GB | 22 GB | 11 GB | 稳态、含索引和缓存 |
| 磁盘占用 | 18 GB | 28 GB | 16 GB | 含数据、索引、WAL |
| 运维负担(0-10) | 7 | 3 | 4 | 见后文详细拆解 |
几点需要说明:
- PGVector 的内存占用高是因为 PG 本身的 shared_buffers、work_mem、maintenance_work_mem 占了一大块,向量索引本身反而不多;
- Milvus 冷启动 90 秒主要是要拉 etcd、加载索引、warmup 缓存,Standalone 已经比集群快很多,集群版这个数字要乘以 3-5;
- PGVector 的索引重建 42 分钟是因为 HNSW 的 maintenance_work_mem 默认只给 64MB,调到 4GB 之后能压到 12 分钟;
- Qdrant 的整体表现最均衡,但在超过 5000 万向量之后会开始吃力,需要上多节点集群。
上面这张表的核心信息是:3 家产品在中等规模(100 万到 1000 万向量)区间下的性能差距,其实没有网上传的那么大——Milvus 的 QPS 优势主要在千万级以上才明显;PGVector 的短板不在稳态 QPS 而在索引重建这件事;Qdrant 在单机稳定性上其实是最省心的。
3. Milvus 生产实测:分布式原生的双刃剑
Milvus 是这 3 家里唯一一个原生就是「面向分布式」设计的。它把存储、计算、协调分成不同角色(DataNode、QueryNode、IndexNode、Proxy、etcd、Pulsar、MinIO),你可以按需扩每一层。这个架构的好处是在千万级以上性能优势明显,坏处是运维复杂度高,中小团队上手成本大。
我们实测下来 Milvus 的几个关键点:
| 场景 | Milvus 表现 | 对生产的影响 |
|---|---|---|
| 稳态 QPS | 单机 780、3 节点集群约 2000 | 千万级以上唯一能撑住的开源方案 |
| 冷启动 | 单机 90s、集群 4-6 分钟 | 故障恢复和滚动升级窗口不能忽视 |
| Compaction | 每天默认触发 1-2 次 | 触发期间 QPS 掉 20-40%,需错开业务高峰 |
| 版本升级 | 大版本每次都有 breaking change | 一年 2 次大版本升级要提前 2 周做测试 |
| 索引重建 | 6 分钟(300 万向量) | 支持 in-place 重建、不阻塞读 |
我们做过一个跨境电商项目,商品描述加评论一共 4200 万向量,用的就是 Milvus 3 节点集群。稳态 QPS 3800、P99 60ms,业务侧完全够用。但整个团队为此付出了什么代价:K8s 集群 6 台机器、专职一个 SRE 半年、外加运维文档 40 多页。这就是 Milvus 的真实成本结构——性能天花板足够高,但要把这个天花板兑现需要一整套 K8s 运维能力。
什么时候真的该上 Milvus:向量数量已经确定要突破 1000 万且未来 12 个月还在涨、团队有 K8s 生产经验、可以接受一个 SRE 一半时间投在这套基础设施上。三条同时满足才上,否则先考虑其他两家。
运维层面最容易踩的坑:一是 etcd 数据没做定期备份,某次 etcd 崩了导致整个集群 metadata 丢失;二是 Pulsar 的 topic 保留策略没调,磁盘涨爆;三是 QueryNode 内存配比没算对,OOM 之后触发恢复要 20 分钟。这些都是我们真踩过的坑。
4. PGVector 生产实测:生态最好但索引重建是命门
PGVector 的最大优势不是性能而是「就是 PG」——已有的备份策略、监控体系、权限模型、SQL 能力全部原地可用。我们做过的项目里,只要向量数量不超过 300 万,PGVector 几乎永远是首选。它的性能实测数据:
| 场景 | PGVector 表现 | 优化空间 |
|---|---|---|
| 100 万向量 QPS | 620、P95 45ms | 默认配置已经很好 |
| 300 万向量 QPS | 210、P95 90ms | 需要调 shared_buffers 和 effective_cache_size |
| 1000 万向量 QPS | 60、P95 300ms | 到这里就不建议再用 PGVector 了 |
| 索引重建 | 300 万向量 42 分钟(默认参数) | 调大 maintenance_work_mem 可压到 12 分钟 |
| 并发写入 | 每秒 50-100 条稳定 | 写入更高会拖慢查询 |
PGVector 有一个非常容易被忽略的问题:HNSW 索引在大量 UPDATE 场景下会 bloat。我们见过一个客户的场景,业务侧频繁 UPDATE 向量字段(重新计算 embedding 之后覆盖),一个月之后表膨胀了 3 倍,索引大小翻倍,查询延时明显上升。这时唯一的解决办法是 REINDEX,但 REINDEX 会长时间持写锁,业务几乎必然停摆。
避免这个坑的做法有两个:一是每次 embedding 更新走 DELETE + INSERT 而不是 UPDATE;二是用 pg_repack 做在线索引重建。这两个方案我们在实际项目里都用过,前者代码改动小,后者对 DBA 要求高。
什么时候真的该用 PGVector:向量数量在 300 万以内且未来 6 个月不会翻倍、写入频率不高(每秒 100 条以内)、业务已经在用 PostgreSQL、团队里有 DBA 能力。这 4 条满足 3 条就可以用。
PGVector 生产上线前必做的 3 个调优:shared_buffers 调到内存的 25%、maintenance_work_mem 拉到 4GB 以上(HNSW 建索引期间)、effective_io_concurrency 调到 200 以上(NVMe SSD 场景)。这 3 项调完,性能能比默认配置提升 40% 以上。
5. Qdrant 生产实测:Rust 底座 + 多租户设计最省心
Qdrant 是这 3 家里我们运维最省心的一家。Rust 底座带来的稳定性、单二进制部署带来的简洁、原生的多租户 collection 设计,让它在中等规模(100 万到 5000 万向量)场景下几乎不用操心。
| 场景 | Qdrant 表现 | 适用范围 |
|---|---|---|
| 稳态 QPS(单机) | 620、P99 55ms | 300 万向量、32 核 128G |
| 冷启动时间 | 25s | 生产可接受 |
| 索引重建 | 4 分钟 | 支持后台异步重建、不阻塞读 |
| 内存占用 | 11 GB(300 万向量) | 支持标量量化压到 4 GB |
| 多租户 | 原生 collection 隔离 | 单实例可跑几十个租户 |
| 集群扩容 | 分片自动 rebalance | 扩容窗口 QPS 波动 <10% |
Qdrant 有一些非常好的工程细节:过滤器和向量检索是紧耦合执行的,不像有些库先做向量检索再做后过滤,会导致召回不足;写入是先写 WAL 再更新索引,宕机重启后不会丢数据;量化后的向量可以和原始向量共存,先用量化向量做粗排、再用原始向量做精排,QPS 和 recall 都能兼顾。
我们做过一个 SaaS 项目,客户是给中小企业提供智能客服的,需要给每家企业单独一份知识库。总共 200 多个租户、单租户 5-30 万向量,全部跑在一台 Qdrant 单机上,稳态 QPS 400,P99 70ms,运维只有一个后端兼职。这种场景下 Milvus 是过度设计,PGVector 又扛不住这么多 collection,Qdrant 是最合适的。
什么时候真的该用 Qdrant:向量数量在 100 万到 5000 万、需要多租户隔离、团队没有 K8s 或分布式经验、追求单二进制部署的简洁感。这几条基本对应了国内 80% 的中等规模 AI 项目。
Qdrant 的坑主要在文档和社区:中文资料相对少,遇到高级配置(比如 payload index 和 vector index 的组合调优)需要读英文文档甚至源代码。好在整体逻辑清晰,读源代码的成本不高。
6. 3 类企业规模的推荐组合
上面的实测数据和拆解,最终要落回一张选型表。我们按向量数量和场景把企业 RAG 分成 3 档:
| 规模档位 | 向量数量 | 推荐组合 | 备选 | 一年运维成本预估 |
|---|---|---|---|---|
| 小规模 | < 100 万 | PGVector(复用业务 PG) | Qdrant 单机 | 几乎零额外成本 |
| 中等规模 | 100 万 - 5000 万 | Qdrant 单机或双机 | Milvus Standalone | 硬件 3-8 万,人力 0.2 个 SRE |
| 大规模 | > 5000 万 | Milvus 集群(自建或 Zilliz) | 云托管 VectorDB | 硬件 15-30 万,人力 0.5-1 个 SRE |
需要特别提示的几点:
- 小规模不要为了「以后可能变大」提前上 Milvus:过去 3 年我们统计的 RAG 项目里,超过 60% 的项目 2 年后向量数量还没突破 100 万。把 12 个月内不会用到的复杂度提前引入,是 RAG 项目失败最常见的原因之一。这个道理在AI Agent 落地路线图里也反复讲过。
- 中等规模里 Qdrant 是默认答案:只有 3 种情况下我们会推荐 Milvus——一是团队已经有 K8s 生产经验,二是 12 个月内一定会突破 5000 万,三是需要 DiskANN 这类专门的大规模索引。
- 大规模要认真评估云托管:自建 Milvus 集群一年硬件 + 人力总成本大约在 40-60 万;同规模用 Zilliz Cloud 或腾讯云 VectorDB 一年通常在 30-50 万。如果不是强合规必须自建,托管方案总账更划算。
如果你还在选型阶段没锁定候选,向量数据库怎么选这篇会把 5 家产品的定位讲清楚;如果已经锁定候选到这 3 家,这篇就是接下来的实测手册。
7. 上线前 5 项必测(能救命的清单)
选型只是第一步,真正让项目稳的是上线前的 5 项必测。这个清单我们内部叫「向量库上线红线」,4 条不过关就不推生产。
测项 1:真实 recall 曲线(而不是官方 recall)
用你的真实用户 query(脱敏后)而不是数据集里的 query,跑 1000-5000 条测召回率。目标:不同 top_k(5、10、20、50)下的 recall 分布。合格线:top_k=10 时 recall ≥ 90%,且分布长尾不能有明显断崖。
测项 2:冷启动时间
从进程被 kill 到 QPS 恢复到稳态 80% 用了多久。合格线:单机 <60s,集群 <5 分钟。这个测项决定了你的故障恢复窗口和滚动升级策略,很多团队第一次做灾备演练才发现冷启动比想象中长得多。
测项 3:写压测下的读性能
按你生产的真实读写比(比如 9:1),跑 30 分钟持续压测。合格线:写入不会让读 P99 上升超过 30%。Milvus 的 compaction、PGVector 的 bloat、Qdrant 的 WAL flush 都会在这个测项里暴露。
测项 4:QPS 稳态曲线
不看峰值 QPS,看 24 小时曲线。合格线:不能有周期性掉井(比如每小时或每 6 小时的 GC 或 compaction 触发的性能下坠)。有的话要么调参数错峰、要么加副本。
测项 5:故障恢复演练
kill 主节点,观察集群自愈时间和数据一致性。合格线:集群模式下自愈 <10 分钟、无数据丢失;单机模式下有明确的 backup 恢复流程且演练过至少一次。
下面这张表是我们生产上线前的实际执行清单:
| 测项 | 工具 | 通过标准 | 常见不通过原因 |
|---|---|---|---|
| Recall 曲线 | 自建脚本 + 人工标注 | top_k=10 recall ≥ 90% | HNSW 参数没调、query 分布不均 |
| 冷启动时间 | systemd 计时 | 单机 <60s | 索引不做 warmup、缓存策略默认 |
| 写压测下读性能 | vegeta / wrk + 自建 | 读 P99 上升 <30% | 写入无 rate limit、compaction 未错峰 |
| QPS 稳态曲线 | Prometheus 长跑 | 无周期性掉井 | GC/compaction 未观测、副本不足 |
| 故障恢复 | chaos-mesh 演练 | 集群自愈 <10 分钟 | 无副本、备份策略未演练 |
跑完这 5 项,你才能说这套向量库是「生产可用」而不是「demo 可用」。这个逻辑跟软件维护费的构成那篇里讲的是一致的——真实的成本永远发生在上线之后。
8. AI 化的 3 个运维场景
向量库运维的最大挑战不是「怎么部署」而是「跑起来之后怎么持续调优」。我们过去一年帮客户在 AI Agent 项目里做过的 3 个 AI 化运维场景,能明显降低这一块的人力成本:
场景 1:性能异常自动归因
以前的做法:Grafana 报警之后 SRE 手动去看 QPS、延时、CPU、内存、compaction、GC 各种指标,逐个排查。现在的做法:把 Prometheus 指标、日志、慢查询流水一起喂给 Agent,让它对齐历史正常时段的基线,给出 3-5 条最可能的归因假设并附证据链,SRE 只做决策不做排查。我们做过的一个项目里,这个 Agent 把故障定位时间从平均 45 分钟压到 8 分钟。
场景 2:索引参数自动调优推荐
以前的做法:DBA 根据经验拍参数、跑一轮压测、看结果、再拍新参数,一轮 2-3 天。现在的做法:让 Agent 基于当前的数据量、query 分布、硬件配置和 recall 目标,给出 HNSW M/ef、量化策略、副本数的建议组合,并按预期收益排序。DBA 从「拍参数」变成「审建议」,一轮压到半天。
场景 3:查询模式识别与冷热分离
以前的做法:默认所有数据放在同一层索引里,热点数据也不会自动前置到内存缓存。现在的做法:Agent 每天分析真实 query 的语义分布和访问频次,识别出热点 collection 或 partition,自动做冷热分层——热数据留在 HNSW 内存索引、冷数据迁到 DiskANN 或对象存储。这个场景对 5000 万向量以上的项目非常关键,能把内存成本降 30-50%。
这 3 个场景的共同点:不是让 AI 直接改生产参数,而是让 AI 做推理 + 建议,最后决策和执行还在 SRE 手里。这个分工在我们做的所有 AI Agent 生产项目里都验证过是最稳的——AI Agent 架构范式那篇里把这套「决策辅助 + 人类审批」的模式讲得更细。
写在最后
向量数据库这个话题聊到今天,已经不是「哪家性能最好」的问题,而是「哪家在我的规模、我的团队能力、我的合规约束下总账最划算」的问题。回到开头那家电商客户的故事,他们最后的解决方案不是换向量库,而是把 recall 目标从 92% 降到 88% 换取 top_k=10 而不是 50、把冷启动做了 warmup 脚本、把写入错开业务高峰——3 个调整下来 QPS 从 30 拉回 180,业务侧完全够用。
选型和实测的 5 条铁律:
- 官方 benchmark 只能当参考,生产口径压测必须自己跑,2 者之间有 3-5 倍差;
- 100 万向量以下 PGVector 是默认答案,不要过度工程;
- 100 万到 5000 万这个区间 Qdrant 是运维最省心的选择,不必上 Milvus;
- Milvus 只在 5000 万以上、有 K8s 生产能力时上,且要预留 0.5 个专职 SRE;
- 上线前 5 项必测(recall / 冷启动 / 写压测 / QPS 曲线 / 故障恢复)不做完不推生产。
如果你正在为一个 RAG 项目做向量库的选型压测或上线评估,欢迎把你们当前的向量数量、读写比、recall 目标和硬件配置整理一下,我们可以一起看看哪些口径需要修、哪几项测试还没跑到位。5 年做下来的 2000+ 家企业里,向量库真正吃亏的项目九成九是死在「选型阶段没跑生产口径」这件事上,把这一步做扎实,后面的运维成本会低一个数量级。








