标题:五大向量数据库横评:Milvus vs Qdrant vs Chroma vs ES vs Faiss,到底怎么选?
第一部分:先泼一盆冷水——性能排名是最没用的选型依据
很多横评文章上来就放一张 QPS 排名表,Qdrant 第一、Milvus 第二、Chroma 垫底,然后得出结论“Qdrant 最好”。这种结论在真实工程里几乎没有参考价值。
原因很简单:向量数据库的性能表现高度依赖于数据规模、过滤条件的选择性、索引参数(ef/M/nprobe)、并发模型,甚至客户端语言。同一个数据库,在不同 benchmark 里排名可以相差好几名。比如在 AIMultiple 的单线程测试中,Milvus 排第三;但在另一个 100M 规模的测试中,Milvus 的 QPS 又高于部分竞品。
所以这篇文章不按“谁快谁慢”来组织,而是按“你的架构约束和业务场景最适合哪种设计哲学”来拆解。
第二部分:五款产品的本质差异,不在性能,在架构
Chroma:嵌入式原型工具,不是数据库
Chroma 的定位非常清晰:让 Python 开发者在 5 分钟内跑起来。pip install chromadb,几行代码就能完成向量存储和查询,默认 HNSW 索引,与 LangChain/LlamaIndex 深度集成。
但它的“上限”和“下限”一样明确。Chroma 底层基于 DuckDB + SQLite,单节点性能在 10 万条以内非常流畅,几十万条开始明显变慢,没有横向扩展路径。一旦数据规模超过约 100 万条,迁移是必选项。
判断标准:如果你在写 POC、做本地 RAG demo、或者数据量确定不会超过 10 万条,Chroma 是最省时间的选择。除此之外,它不该出现在生产架构的讨论里。有个真实案例:一个电商推荐系统第一版用了 Chroma,数据涨到 5000 万条后查询延迟从 20ms 涨到 800ms,紧急迁移到 Milvus 多花了 8 个人周。
Milvus:为“超大规模”牺牲了运维简洁性
Milvus 的架构选择是存算分离 + 微服务化:Proxy、QueryCoord、DataCoord、QueryNode、DataNode 各司其职,底层索引文件落在对象存储(MinIO/S3)上。这种设计带来的能力是真实的:十亿级向量、K8s 弹性扩缩容、GPU 加速、多种索引类型(HNSW、IVF_FLAT、DiskANN 等)。
代价同样真实:运维复杂度是五款里最高的。你需要理解各个组件的角色、协调对象存储、管理索引构建的调度。Milvus 也有 Standalone 模式用于小规模,但这时候它的架构优势发挥不出来,运维成本却依然高于 Qdrant 单机。
判断标准:数据量在亿级以上,或者明确需要多业务线共用一个向量集群、且团队有 K8s 运维能力,Milvus 是经过验证的选择。如果数据量在千万级以下,Milvus 的分布式架构是过度设计。
Qdrant:用 Rust 重写了“过滤”这件事
Qdrant 的核心差异化不在“快”,而在过滤检索的执行方式。传统向量数据库的做法是“先做 ANN 检索,再对结果做元数据过滤”(post-filtering),或者“先按条件过滤,再在小候选集上做 ANN”(pre-filtering)。前者在过滤条件严格时会丢失结果,后者在候选集过小时精度下降。Qdrant 的做法是把过滤嵌入 HNSW 图遍历过程本身:遍历时只走满足 payload 条件的节点,而不是事后裁剪结果。
这个设计的实际收益在过滤条件高选择性的场景下最明显:当过滤后的候选集只占总量的 5% 时,Qdrant 的延迟仍能保持基线水平,而“先检索后过滤”方案的延迟会因为候选集不足而恶化。加上 Rust 实现带来的低延迟和 Binary Quantization 的 32 倍内存压缩,Qdrant 在单机性能和过滤体验的平衡上是目前最成熟的。
判断标准:如果你的 RAG 场景需要频繁按租户 ID、时间范围、类别标签等条件过滤,且数据量在千万到亿级之间,Qdrant 是首选。它的单机起步成本极低(一个二进制文件),集群模式比 Milvus 轻得多。
Elasticsearch:赢在“你已经有了 ES”
ES 做向量检索的技术路线是在已有的倒排索引和全文检索体系上叠加 kNN。它支持近似 kNN(HNSW)和精确 kNN(暴力扫描),混合搜索(BM25 + 向量)是它的天然强项。
但 ES 的向量能力始终是“扩展功能”而非核心设计目标。资源消耗高(JVM 堆内存 + 向量索引额外占用),在纯向量检索场景下性能不如专用向量库,P99 延迟和吞吐量在百万级以上规模时劣势明显。
判断标准:“已经有 ES 集群”是选 ES 做向量检索的最强理由。如果你的应用本来就在用 ES 做全文搜索、日志分析,叠加向量检索可以避免引入新组件,运维团队也不需要学习新系统。但如果是从零开始、以向量检索为核心需求,ES 不是最优解。
Faiss:不是数据库,是索引库
Faiss 经常出现在“向量数据库”横评里,但它本质上是一个C++ 相似度搜索库,提供 Flat、IVF、HNSW、PQ 等多种索引实现,GPU 加速能力突出,十亿级数据下延迟可以做到极低。
问题在于,Faiss没有持久化、没有 API 服务、没有元数据过滤、没有分布式协调。你需要自己封装服务层、自己实现数据写入和索引重建、自己处理高可用。它更适合作为嵌入层加速引擎被其他系统调用——事实上 Milvus 的底层索引就构建在 Faiss/HNSWlib 之上。
判断标准:追求极致性能的离线实验、需要 GPU 加速的嵌入计算密集型场景,或者作为已有系统的底层检索组件。把它当“数据库”来用,等于自己造一个 Milvus。
第三部分:一张表看清五款产品的硬约束
| Chroma | Milvus | Qdrant | Elasticsearch | Faiss | |
|---|---|---|---|---|---|
| 本质 | 嵌入式向量库 | 分布式向量数据库 | 独立向量数据库 | 搜索与分析引擎 | 向量索引库 |
| 架构 | 单进程,DuckDB+SQLite | 存算分离,微服务 | Rust 单体/轻集群 | 分布式搜索集群 | 本地库 |
| 数据上限 | ~10万-100万 | 十亿级 | 十亿级 | 百万-千万级(向量场景) | 十亿级(单机/GPU) |
| 过滤检索 | 基础元数据过滤 | 标量过滤 | 过滤内嵌 HNSW,最强 | 强(倒排+向量) | 需自行实现 |
| 混合搜索 | ✗ | ✓ | ✓ | ✓(BM25+向量) | ✗ |
| 分布式 | ✗ | ✓ | ✓(Raft,轻量) | ✓ | ✗ |
| 运维复杂度 | 极低 | 高 | 中低 | 中高 | 极高(需自建服务) |
| 核心代价 | 规模天花板 | 运维负担 | 超大规模集群经验少于 Milvus | 向量为扩展功能,资源效率低 | 一切都要自己做 |
数据来源综合了多份横评与基准测试。
第四部分:选型决策树(直接抄作业)
不要记性能数字,记判断顺序:
第一问:你在做 POC 还是上生产?
- POC/本地 demo →Chroma。5 分钟能跑通的事,不值得花 5 小时部署 Milvus。
- 上生产 → 进入第二问。
第二问:你的数据量级和过滤需求是什么?
- 千万级以下 + 过滤条件简单 →Qdrant 单机。一个二进制文件起步,性能好,运维几乎为零。
- 千万到亿级 + 过滤条件频繁且选择性高(多租户、时间范围、标签) →Qdrant。过滤内嵌 HNSW 的设计在这个区间优势最大。
- 亿级以上 + 多业务线共用 + 团队有 K8s 能力 →Milvus。存算分离和弹性扩缩容是为此设计的。
第三问:你已经有 ES 集群吗?
- 是,且向量检索不是核心瓶颈 →ES。不引入新组件的工程价值,往往大于性能表上几毫秒的差距。
- 否 → 回到第二问。
第四问(特殊情况):你是否需要把检索嵌入到自己的 C++ 服务里,或者需要 GPU 加速的极致性能?
- 是 →Faiss,但请清醒地认识到你是在“用一个库造一个数据库”,服务层、持久化、过滤、高可用都需要自己写。
第五部分:比选型更重要的事——检索质量不取决于数据库
有一个事实经常被横评文章忽略:RAG 系统的最终效果,向量数据库只贡献了其中一环。分块策略(chunk_size 过大切断语义、过小丢失上下文)、是否引入 Rerank、是否做混合检索、Embedding 模型是否匹配业务语言,这些因素对召回质量的影响远大于“选 Milvus 还是 Qdrant”。
一个用 Qdrant + 精心设计的 Rerank 流水线的系统,完全可以击败一个用 Milvus 但粗暴分块、不做重排的系统。选型的意义是避免在规模和运维上踩坑,而不是“选对数据库就等于RAG做得好”。
第六部分:一句话结论
- Chroma:原型阶段的默认选项,生产阶段的债务。
- Milvus:超大规模的正确工具,前提是你养得起它的运维复杂度。
- Qdrant:单机到中等集群区间里,过滤检索和运维成本的平衡点做得最好的一款。
- Elasticsearch:已有 ES 生态时的“顺便选项”,从零开始则以向量为核心需求时不选它。
- Faiss:嵌入系统的加速引擎,不是数据库。
你目前在用哪款向量数据库?数据量到了什么量级?有没有遇到过滤后召回“缩水”的问题?评论区聊聊,我会挑典型场景单独写优化方案。