pgvector:向量搜索在 PostgreSQL
pgvector 是 PostgreSQL 的一个开源扩展(采用宽松的 PostgreSQL 许可证),可为您已经管理的数据库添加向量存储与检索功能,列最多可索引 2 000 个维度(半精度下为 4 000 个维度)。对于包含几十万个文本片段的本地语料库,使用它意味着少运维一个服务,还能使用有效的 SQL 过滤条件,无需另外维护与关系型数据的同步。
pgvector 是 PostgreSQL 的一个扩展,可为您已经管理的数据库添加向量存储和检索功能。对于大多数本地文档检索项目,这意味着少运行一个服务、少安排一项备份,而且 SQL 过滤确实有效——包括按访问权限过滤。该项目采用 PostgreSQL 许可证维护,托管在 GitHub 上。截至 2026 年 9 月底,其 GitHub 星标数已超过 23,000,版本为 0.8.6,兼容 PostgreSQL 13 及更高版本。
#选择它的理由:无需增加服务
本地文档处理系统已经运行着模型服务器、编码环节和文档存储。添加专用向量数据库,就意味着多一个容器、多一个端口、多一份需要备份的内容,以及多一个可能在删除文档时与您的关系型数据不同步的组件。
如果已经使用 PostgreSQL——业务应用中几乎总是如此——pgvector 就能消除这一整类问题。文本片段存储在一张表中,与其来源文档放在一起管理,通过外键保持一致性;删除操作也会按预期级联生效,无需另行编写或监控清理任务。此外,该项目还提供精确和近似搜索,支持单精度、半精度、二进制和稀疏向量,以及五种距离度量(L2、点积、余弦、L1、汉明、Jaccard),并且无需额外成本即可继承 PostgreSQL 的 ACID 特性、时间点恢复和连接查询功能。
#实际运作方式
你的文档,你的 AI:基于你的 PDF、笔记和邮件的可靠本地 RAG——无需向云端发送任何内容。
- 在线空间,终身可用
- PDF + 文件
- 30 天内退款
您在常规数据列旁边存储一列向量。查询会按各行向量与问题向量之间的距离对行进行排序,并返回距离最近的行。三种距离运算符可覆盖常见场景,所选运算符必须与嵌入模型的约定一致:两者不匹配,是结果不易察觉地变差的最常见原因。对于归一化到长度为1的向量(OpenAI和大多数较新的嵌入模型都属于这种情况),点积计算最快,且排序结果与余弦相似度相同。
| 元素 | 这是什么 | 需重点关注 |
|---|---|---|
| 向量列 | 固定维度的浮点数数组 | 维度由嵌入模型决定;要改变维度,就必须对所有内容重新编码 |
| 距离运算符 | 余弦、点积或欧几里得距离(L2) | 必须与模型匹配 |
| HNSW索引 | 图结构索引,查询速度快 | 构建缓慢且占用大量内存;自 0.5 版本起,是一个合理的默认选择 |
| IVFFlat索引 | 基于分区的索引,构建成本较低 | 待有了具有代表性的数据后再创建 |
| 无索引 | 精确遍历所有数据行 | 数据量在几万行以内时完全可行 |
#入门所需的基本 SQL
- 01启用扩展CREATE EXTENSION IF NOT EXISTS vector; —— 只需这一条命令,每个数据库执行一次。
- 02添加列ALTER TABLE chunks ADD COLUMN embedding vector(1024); —— 维度必须与所使用的嵌入模型的输出维度完全一致。
- 03在索引之前加载数据在尚未创建索引时,通过 COPY 批量加载数据会更快;等已有的数据行达到具有代表性的数量后,再创建索引。
- 04创建索引CREATE INDEX CONCURRENTLY ON chunks USING hnsw (embedding vector_cosine_ops); —— CONCURRENTLY 选项可避免在构建索引期间阻塞写入;对于大型表,索引构建会耗费较长时间。
- 05查询SELECT contenu FROM chunks WHERE document_id IN (SELECT id FROM documents WHERE utilisateur_autorise($1)) ORDER BY embedding <=> $2 LIMIT 5; —— 能在单个查询中实现权限过滤和相似度排序。
#维度限制的具体情况
pgvector 定义了四种列类型,每种类型都有自己的可索引维度上限。标准 vector 类型(单精度,每个元素 4 字节)最多可对 2 000 维建立索引,涵盖了大多数常见的开源嵌入模型(384 至 1 024 维)。更大的模型,例如 OpenAI 的 text-embedding-3-large,默认有 3 072 维,超过了这一上限:文档给出的解决办法是,在生成嵌入时降低维度(API 支持),或者改用 halfvec 类型。halfvec 以半精度存储(每个元素 2 字节,占用空间减半),最多可对 4 000 维建立索引。bit 类型(二进制向量,使用汉明距离或 Jaccard 距离)最多支持 64 000 个可索引维度,而 sparsevec 类型(稀疏向量)最多可对 1 000 个非零元素建立索引。超过这些上限后,PostgreSQL 仍可存储该列(vector、halfvec 和 sparsevec 最多支持 16 000 维),但无法建立索引,因此只能通过遍历进行精确搜索。
#过滤机制及访问权限
实际问题很少涉及整个语料库:我们想要的是与某个服务相关、晚于某个日期,而且位于该用户有权阅读的文档中的文本片段。在专用向量数据库中,这需要使用元数据过滤器,并处理其特定语法和边界情况。在 PostgreSQL 中,则是在按相似度排序的同时使用 WHERE 子句,必要时再关联你的用户表。
该项目自身文档中记载了一个值得提前了解的陷阱,以免到了生产环境才发现:使用近似索引(HNSW 或 IVFFlat)时,过滤条件是在索引扫描之后应用的,而不是之前。如果某个条件只保留 10% 的行,且 hnsw.ef_search 参数采用默认值 40,那么平均只会返回 4 行,而不是请求的 10 行。自 0.8.0 版本起,官方提供了名为迭代索引扫描的解决方案(SET hnsw.iterative_scan = strict_order):它会自动再次执行扫描,直到找到足够多的结果,而不是悄无声息地返回截断的结果集。
#它的局限
- 大规模场景下的内存占用
- 数百万个全精度向量会占用大量内存;halfvec 和二值量化可以减少内存占用,但专用引擎原生支持更高程度的压缩。这是最明显的差距。
- 索引构建时间
- 在一张非常大的表上创建HNSW索引耗时较长且资源消耗大;在生产环境中,使用CREATE INDEX CONCURRENTLY构建索引可避免操作期间阻塞写入操作。
- 资源竞争
- 将计算负载较重的向量检索与事务负载放在一起,就意味着两者共用同一台服务器。只读副本能有所帮助,而将两者的职责分离效果更好。
- 向量的维度
- 索引向量的维度上限取决于其类型(vector 为 2 000 维,halfvec 为 4 000 维)。常见模型都在这一限制内;维度非常高的模型则需要降维或量化。
- 混合搜索
- PostgreSQL 支持全文检索(tsvector),您可以将其与向量距离检索结合使用,但如何让它易于使用,需要您自行实现:必须分别执行两次查询,再合并排序结果,例如使用倒数排名融合(Reciprocal Rank Fusion),而不是通过一次查询直接获得原生混合评分。
- 横向扩展能力
- 当扩展到多台服务器时,文档中介绍的方案是使用 PostgreSQL 只读副本,或采用 Citus、PgDog 等分配工具——这意味着要额外增加一个组件,与最初的论点相反。
#pgvector 或专用数据库
问题不在于哪一个客观上更好,而在于哪一个更符合您目前的情况。如果 PostgreSQL 已经是应用的权威数据源,存储着计费数据、账户和源文档,pgvector 就更有优势。如果向量数量或查询吞吐量超过了单台事务服务器在不影响应用其他部分的情况下所能承受的范围,专用引擎就更有优势;如果团队出于运维考虑,而非单纯追求性能,希望将 AI 组件与信息系统的其他部分隔离,专用引擎也更有优势。
| 情况 | 选择 |
|---|---|
| PostgreSQL 已部署,片段数量少于数十万个 | pgvector,轻松胜任 |
| 向量必须与关系型数据保持一致 | pgvector:交易免费 |
| 基于现有权限的精细过滤 | pgvector |
| 嵌入模型维度超过4000,且不可进行降维处理 | 检查 sparsevec 类型,或专为这种情况设计的数据库 |
| 数百万向量,大量查询 | 专用引擎(Qdrant、Milvus) |
| 在交互式笔记本中制作原型 | 任选其一,该选择可随时更改 |
- Qdrant:专用向量数据库
- Milvus,当数据量超过pgvector的承载能力时
- FAISS:向量搜索背后的库
- 构建完整的RAG链路
- 选择嵌入模型
- QuelLLM 本地 RAG 工具包:所有组件汇集于同一页面
- 来源:pgvector 在 GitHub 上的官方仓库
- 来源:pgvector 索引和类型文档
- 来源:pgvector 扩容指南
#FAQ
pgvector 用于 RAG 时,速度够快吗?+
pgvector 还是 Qdrant?+
选择哪个索引,HNSW 还是 IVFFlat?+
可以按元数据进行过滤吗?+
如果更换嵌入模型会怎样?+
我的嵌入模型维度超过2000,该如何处理?+
如何诊断向量查询缓慢?+
有反馈、发现了错误,或想补充说明?请告诉我们,让这份指南对每个人都更有帮助。