向量数据库 PGVector、Qdrant 与 Milvus
2026/5/5 9:20:15 网站建设 项目流程

一、PGVector

为什么推荐 PGVector 作为 RAG 的入门首选?

理由很直接——你的项目大概率已经在用 PostgreSQL
直接加一个扩展,不需要引入新的数据库组件,运维成本最低。DBA 会用 PG,就会维护 PGVector。这种“复用已有基础设施”的价值,在实际项目里非常实在。

1.1 PGVector 能做什么(本质)

PGVector 给 PostgreSQL 加了一个新的数据类型VECTOR,你可以在普通的表里加一列向量,然后对这列向量做相似度搜索。
查询时,用“向量相似度排序”替代普通 SQL 的ORDER BY

三种距离算法

运算符距离类型适用场景
<->欧氏距离(L2)坐标空间,对向量幅度敏感
<=>余弦距离文本语义搜索首选(只看方向,不看幅度)
<#>内积(负数)向量已归一化时等效于余弦距离

文本 RAG 场景几乎都用余弦距离。因为不同长度的文本,Embedding 向量的幅度可能不同,但语义方向是相似的。余弦距离只看方向,不受幅度影响,更适合语义搜索。

1.2索引类型:HNSW vs IVFFlat

这是 PGVector最重要的选择之一,直接影响搜索速度和精度。

什么是向量索引?

没有索引时,向量搜索要把查询向量和库里每一条记录都算一次距离(全量扫描)。100 万条数据,就要算 100 万次距离,O(n) 复杂度,数据量大了根本跑不动。

向量索引通过构建特殊的数据结构,让搜索时只计算一小部分候选向量的距离。代价是:不保证找到“最精确”的结果,只保证找到“足够好”的近似结果——即ANN(近似最近邻)搜索

1.2.1 HNSW(层级小世界网络)

HNSW 构建了一个多层的图结构:

HNSW 索引结构(简化示意) 层 2(稀疏): A ←————→ F ←——→ K ↑ 层 1(中等): A ←——→ D ←——→ F ←——→ H ←——→ K ↑ 层 0(密集): A-B-C-D-E-F-G-H-I-J-K(所有节点)

查询时从高层稀疏图开始找大方向,逐层往下精化,最终在底层找到精确候选——就像在地图上先定位到城市,再找街道,再找门牌号,高效且准确。

HNSW 的优点

  • 查询速度快,延迟低

  • 召回率高(精度好)

  • 支持增量插入(随时插入新数据,不需要重建索引)

HNSW 的缺点

  • 建索引较慢(但通常是一次性操作)

  • 内存占用较大(索引结构要常驻内存)

大多数 RAG 场景推荐 HNSW。

1.2.2 IVFFlat(倒排文件 + 扁平量化)

IVFFlat 的思路:先把向量空间划分成若干个“桶”(Cluster),每次查询只搜最近的几个桶,不搜全部。

IVFFlat 索引结构(简化示意) 向量空间 ┌──────────────────────────────────┐ │ 桶1 桶2 桶3 桶4 桶5 │ │ ··· ··· ··· ··· ··· │ └──────────────────────────────────┘ ↑ 查询向量先判断属于哪个桶附近,只在附近桶里搜

IVFFlat 的优点

  • 建索引快

  • 内存占用小

IVFFlat 的缺点

  • 查询速度相对较慢

  • 召回率略低(向量被错分到错误桶的情况不可避免)

  • 需要先有足够量的数据才能建索引(通常要求 > 1000 条,聚类才有意义)

适合 IVFFlat 的场景:数据量百万级以上、批量入库(非实时插入)、对内存比较敏感。

1.2.3两者对比

维度HNSWIVFFlat
查询速度较慢
查询精度(召回率)中等
建索引速度
内存占用
增量插入友好较麻烦(需定期重建)
数据量要求无特殊要求> 1000 条才有意义
推荐场景大多数 RAG 场景大规模批量场景

1.3 HNSW 的关键参数:m 和 ef_construction

HNSW 有两个建索引时的关键参数,影响精度和资源消耗的权衡。

参数 m:每个节点的最大连接数

m决定了 HNSW 图的“密度”——每个节点最多连接几个邻居。

  • m越大:图越密,搜索越准,但内存占用越大、建索引越慢

  • m越小:内存省,但精度降低

通用推荐值:m = 16

  • 调大 m(如 32~64):对召回率要求极高(如法律文档检索),代价是内存翻倍

  • 调小 m(如 8):内存极度紧张时,精度会下降但速度更快

参数 ef_construction:建索引时的搜索宽度

ef_construction控制建索引时的精度——在往图里插入每个节点时,搜索多少候选邻居来决定最终连接。

  • ef_construction越大:索引越精确,但建索引越慢

  • ef_construction越小:建索引快,但索引质量略低

通用推荐值:ef_construction = 64

建议:这两个参数入门时不要纠结,16/64就是很好的默认值。等到真正遇到性能瓶颈,再基于实际测量调整。

1.4查询时的 ef_search:精度和速度的旋钮

建好索引后,查询时还有一个参数ef_search,控制查询时搜索的候选数量。

  • ef_search越大:查询越准(召回率高),但耗时越长

  • ef_search越小:查询越快,但可能漏掉一些相关结果

默认值通常是40

这个参数的意义是:你可以在不重建索引的情况下,灵活地在查询精度和速度之间调整。

场景推荐 ef_search
精度优先(如法律条文检索)100–200
速度精度平衡(大多数场景)40–100(默认附近)
速度优先(高并发低延迟)20–40

1.5距离算法和相似度分数的关系

这里有个容易混淆的地方,鸡哥单独说清楚。

余弦距离的范围是[0, 2]

  • 0→ 完全相同

  • 2→ 完全相反

但 RAG 框架里通常展示的是相似度分数,它是对余弦距离的转换:

相似度 = 1 - 余弦距离
  • 完全相同 → 余弦距离 = 0 → 相似度 = 1.0

  • 不相关 → 余弦距离 ≈ 1 → 相似度 ≈ 0.0

  • 完全相反 → 余弦距离 = 2 → 相似度 = -1.0

所以设置“相似度阈值”时,例如similarityThreshold = 0.6,表示“只要余弦相似度 ≥ 0.6 的结果”。

阈值怎么设?

没有通用答案,要根据数据和模型实测。鸡哥的经验:

  • 中文业务文档(通义千问 Embedding)0.5–0.7比较合理

  • 英文技术文档(OpenAI Embedding)0.6–0.8

  • 第一次调试:先设0.3,看能不能搜到东西,再逐步调高

阈值设太高(比如 0.9),会过滤掉大量相关结果,知识库形同虚设。
阈值设太低,会引入大量噪音,浪费 LLM 的上下文窗口。

1.6 Metadata 过滤:向量搜索 + 结构化过滤组合

PGVector 支持在向量搜索的同时按 Metadata 过滤。这个功能看起来简单,但设计得好可以大幅提升检索精度

1.6.1场景举例

知识库里有:产品手册(category=manual)、FAQ(category=faq)、政策文档(category=policy)。
用户提问:“退款要多久?”

  • 普通向量搜索:可能找到来自产品手册的内容(里面也提到了退款)

  • 加 Metadata 过滤:只在category=faq里搜,精准命中 FAQ 里的退款条款

1.6.2Metadata 设计建议

建议入库时至少标注:

{ "source": "文件名或 URL", "category": "文档类别", "version": "版本号", "upload_date": "入库时间" }

注意:Metadata 过滤和向量搜索是“先过滤后搜索”——先通过 Metadata 缩小候选集,再在候选集内搜向量。
过滤条件越严格,候选集越小,TopK 能找到的结果就越少(甚至可能不足 K 个)。合理设计 Metadata 粒度很重要。

1.7性能基准:PGVector 在不同规模下的表现

测试环境:HNSW 索引(m=16, ef_construction=64),1536 维向量,普通 4 核 8G 服务器。

数据量查询延迟(TopK=5)内存占用(向量索引)推荐场景
1 万条< 10ms~100MBDemo、小型工具
10 万条10–30ms~1GB企业知识库
100 万条30–100ms~10GB平台级中型产品
1000 万条100ms+内存可能撑不住考虑换专业向量库

对于中小型企业知识库(文档数百到数千个,分块后数万条向量),PGVector 性能完全够用,查询延迟可以控制在 30ms 以内。

PGVector 的实际瓶颈通常不在向量搜索,而在写入速度。
大规模批量入库时,Embedding 模型的调用速度(每条都要调用一次 API)才是真正的瓶颈。

1.8什么时候 PGVector 开始显现局限?

见过一些开始觉得 PGVector 不够用的情况:

  1. 数据量超过几百万条:查询延迟开始超出要求,HNSW 索引的内存占用可能超出单机可用内存。

  2. 多租户向量隔离需求:比如 SaaS 产品,每个客户的知识库要完全隔离。PGVector 只能靠 Metadata 过滤实现“逻辑隔离”,没有真正的物理隔离。专业向量库的 Collection 概念更适合这个场景。

  3. 向量 + 复杂结构化条件的混合查询:例如“在最近 7 天上传的、来自技术部门的、内容和问题相关的文档块”。这类复杂混合查询,PGVector 的过滤性能不如专业向量库。

  4. 极高并发:PGVector 依赖 PostgreSQL 的连接池,高并发场景下会遇到连接数上限和锁竞争问题。

1.9生产部署的几个要点

1. 不要用initialize-schema: true管理生产 DDL

让框架自动建表只适合开发和 Demo。生产环境的表结构变更要纳入版本管理(Flyway、Liquibase 或手动维护 SQL 文件),方便追踪和回滚。

2. 向量表要定期做 VACUUM

大量删除和更新向量后,PG 的 MVCC 机制会留下“死元组”,占用磁盘空间并影响查询性能。定期执行:

VACUUM ANALYZE vector_store;

3. 监控向量表大小和索引状态

特别是 HNSW 索引在内存里的占用。如果机器内存不足,索引会被频繁换入换出,查询延迟会大幅上升。

4. 数据备份和恢复策略

向量库里存的是 Embedding 结果。如果 Embedding 模型没变,数据丢失可以通过重新入库恢复(只是费时间)。但建议还是纳入常规备份。

二、Qdrant——高性能、现代感强的专业向量库

Qdrant 是用Rust写的,这一点非常重要——Rust 的内存安全特性和零成本抽象让 Qdrant 在性能和稳定性上有天然优势,单机可以支撑千万级向量,内存占用还比同等 Java/Go 实现低。

2.1Qdrant 相比 PGVector 的核心优势

  • 多 Collection 原生支持:每个 Collection 是独立的向量空间,有独立的维度和索引。
    鸡哥见过的一个场景:一个平台有“产品手册”、“FAQ”、“政策文档”三个知识库,用 Qdrant 就是三个 Collection,天然隔离;用 PGVector 只能靠 Metadata 字段区分,查询时加过滤条件,不够干净。

  • Payload 过滤性能优秀:Qdrant 的过滤机制是专门为“向量+过滤”组合查询设计的,支持在过滤之前或之后做向量搜索,有复杂优化器。在同样的数据量下,复杂过滤条件的性能比 PGVector 好很多。

  • Rust 实现的性能和稳定性:高并发场景下,Qdrant 的延迟抖动很小。PGVector 在高并发下可能因为 PG 锁机制出现延迟毛刺。

  • 自带图形化界面:启动后就有 Dashboard,可以直接在界面里看 Collection、查数据、测搜索,调试很方便。鸡哥每次接触新知识库,先在 Qdrant 的界面里搜几个测试问题看看效果。

2.2 Qdrant 的适用场景

  • 场景 A:中大型企业知识库(数百万条向量)
    → 单机 Qdrant 就够,比 PGVector 有明显性能优势

  • 场景 B:SaaS 平台的多租户知识库
    → 每个租户一个 Collection,物理隔离,简洁清晰

  • 场景 C:从 PGVector 升级的首选
    → 部署简单(单 Docker),Spring AI 支持好,代码层不用改

  • 场景 D:对运维复杂度有约束的团队
    → Qdrant 单进程就能跑,不像 Milvus 需要多个组件

2.3 Qdrant 的局限

Qdrant 不适合“数据量亿级以上 + 需要水平扩展”的场景——它的分布式模式(Qdrant Cloud 或自建集群)相对复杂,不如 Milvus 在分布式层面成熟。

三、Milvus——分布式大规模场景的重炮

Milvus 是由 Zilliz 开源的分布式向量数据库,支持十亿级向量,内置分布式能力,是向量数据库领域的“大规模场景专家”。

3.1Milvus 的架构特点

Milvus 是真正的分布式系统,组件分离:

┌─────────────────────────────────────────────────────────────┐ │ Milvus 分布式架构 │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Query │ │ Data │ │ Index │ ← 计算节点 │ │ │ Node │ │ Node │ │ Node │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ ↓ ↓ ↓ │ │ ┌─────────────────────────────────────┐ │ │ │ 消息队列(Pulsar/Kafka) │ ← 数据流 │ │ └─────────────────────────────────────┘ │ │ ↓ │ │ ┌─────────────────────────────────────┐ │ │ │ 对象存储(MinIO/S3) │ ← 持久化 │ │ └─────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘

这个架构的好处:每一层可以独立扩展,计算和存储分离,扛得住真正的大规模。

代价:部署复杂度很高。一个完整的 Milvus 集群需要:协调节点(Coordinator)、查询节点、数据节点、索引节点、消息队列(Pulsar 或 Kafka)、对象存储(MinIO 或 S3)。对一个没有专职运维的中小团队来说,光是搭起来就要花不少时间。

3.2Milvus 的适用场景

  • 场景 A:数据量亿级以上的大规模系统
    → 电商推荐系统(商品 Embedding + 用户行为 Embedding)
    → 大型内容平台的语义搜索(文章、视频描述)
    → 超大规模企业文档库(集团级、跨公司的知识管理平台)

  • 场景 B:需要水平扩展能力
    → 业务增长快,向量量每月翻倍
    → 需要在线扩容不停服

  • 场景 C:有专职运维团队
    → 公司有 DBA/SRE,能维护多组件分布式系统

对大多数企业知识库项目,Milvus 是过度设计。如何判断:如果你的知识库文档不超过几十万,团队没有专职运维,用 Milvus 是给自己找麻烦。

四、三个向量库的全面对比

维度PGVectorQdrantMilvus
数据量级上限百万条以内(舒适)千万级(单机)十亿级(分布式)
部署复杂度极低(已有 PG 直接用)低(单 Docker)高(多组件)
Payload/Metadata 过滤一般优秀(专门优化)优秀
多租户隔离靠 Metadata 过滤(逻辑隔离)Collection 原生隔离Collection 原生隔离
写入吞吐极高
查询延迟中(10万条 < 30ms)低(Rust 实现)低(分布式优化)
内存占用中(随 PG 共享)低(Rust 高效利用)高(多节点)
运维成本低(复用 DBA 技能)中(需要学习 Qdrant)高(分布式运维)
Spring AI 支持完整完整完整
图形化界面需要额外工具(pgAdmin)内置 Dashboard需要 Attu 等工具
云托管RDS for PG(各云厂商)Qdrant CloudZilliz Cloud
开源协议Apache 2.0Apache 2.0Apache 2.0
适用场景中小项目,已有 PG中大型项目,性能有要求超大规模,分布式

五、选型决策树

你的 RAG 系统数据量是多少? │ ├── < 50 万条,且已有 PostgreSQL │ → PGVector(复用已有基础设施,最省事) │ ├── 50 万 - 1000 万条,或有多租户需求 │ → Qdrant(高性能,运维简单,Collection 隔离) │ → 也可以 PGVector + 垂直扩容先撑一段时间 │ └── > 1000 万条,或需要水平扩展 │ ├── 有专职运维团队,数据量亿级 │ → Milvus(真分布式,扛得住) │ └── 没有专职运维,但数据量大 → Qdrant Cloud 或 Zilliz Cloud(云托管,省运维) 其他约束条件: │ ├── 数据不能上云,必须私有化部署 │ → Qdrant 单机(运维最简单) │ → Milvus 单机版(比集群版简单,但组件还是多) │ ├── 团队熟悉 SQL,不想学新查询语言 │ → PGVector(SQL 查向量) │ └── 需要最快速的 Demo / 验证 → PGVector(docker 一行,最快)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询