进阶 11 分钟Stack

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 及更高版本。

作者: Mohamed Meguedmi·更新于 2026-09-28·已在 Windows、macOS 和 Linux 上测试

#选择它的理由:无需增加服务

本地文档处理系统已经运行着模型服务器、编码环节和文档存储。添加专用向量数据库,就意味着多一个容器、多一个端口、多一份需要备份的内容,以及多一个可能在删除文档时与您的关系型数据不同步的组件。

如果已经使用 PostgreSQL——业务应用中几乎总是如此——pgvector 就能消除这一整类问题。文本片段存储在一张表中,与其来源文档放在一起管理,通过外键保持一致性;删除操作也会按预期级联生效,无需另行编写或监控清理任务。此外,该项目还提供精确和近似搜索,支持单精度、半精度、二进制和稀疏向量,以及五种距离度量(L2、点积、余弦、L1、汉明、Jaccard),并且无需额外成本即可继承 PostgreSQL 的 ACID 特性、时间点恢复和连接查询功能。

#实际运作方式

本地 RAG 工具包

你的文档,你的 AI:基于你的 PDF、笔记和邮件的可靠本地 RAG——无需向云端发送任何内容。

  • 在线空间,终身可用
  • PDF + 文件
  • 30 天内退款

您在常规数据列旁边存储一列向量。查询会按各行向量与问题向量之间的距离对行进行排序,并返回距离最近的行。三种距离运算符可覆盖常见场景,所选运算符必须与嵌入模型的约定一致:两者不匹配,是结果不易察觉地变差的最常见原因。对于归一化到长度为1的向量(OpenAI和大多数较新的嵌入模型都属于这种情况),点积计算最快,且排序结果与余弦相似度相同。

拼图的各个部分
元素这是什么需重点关注
向量列固定维度的浮点数数组维度由嵌入模型决定;要改变维度,就必须对所有内容重新编码
距离运算符余弦、点积或欧几里得距离(L2)必须与模型匹配
HNSW索引图结构索引,查询速度快构建缓慢且占用大量内存;自 0.5 版本起,是一个合理的默认选择
IVFFlat索引基于分区的索引,构建成本较低待有了具有代表性的数据后再创建
无索引精确遍历所有数据行数据量在几万行以内时完全可行

#入门所需的基本 SQL

  1. 01
    启用扩展
    CREATE EXTENSION IF NOT EXISTS vector; —— 只需这一条命令,每个数据库执行一次。
  2. 02
    添加列
    ALTER TABLE chunks ADD COLUMN embedding vector(1024); —— 维度必须与所使用的嵌入模型的输出维度完全一致。
  3. 03
    在索引之前加载数据
    在尚未创建索引时,通过 COPY 批量加载数据会更快;等已有的数据行达到具有代表性的数量后,再创建索引。
  4. 04
    创建索引
    CREATE INDEX CONCURRENTLY ON chunks USING hnsw (embedding vector_cosine_ops); —— CONCURRENTLY 选项可避免在构建索引期间阻塞写入;对于大型表,索引构建会耗费较长时间。
  5. 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 维),但无法建立索引,因此只能通过遍历进行精确搜索。

→
量化并不仅仅是一个存储细节
从 vector 类型改为 halfvec 类型,会使每行数据的存储大小减半,从而让内存容纳更多索引,并加快大规模查询,而无需更改嵌入模型。二进制量化(bit 类型)更进一步:先压缩用于搜索的索引,再基于完整向量重新排序,恢复损失的精度——这是项目自身文档记载的方法,用于让大型索引完全驻留在内存中,而不是因内存不足而溢出到磁盘。

#过滤机制及访问权限

实际问题很少涉及整个语料库:我们想要的是与某个服务相关、晚于某个日期,而且位于该用户有权阅读的文档中的文本片段。在专用向量数据库中,这需要使用元数据过滤器,并处理其特定语法和边界情况。在 PostgreSQL 中,则是在按相似度排序的同时使用 WHERE 子句,必要时再关联你的用户表。

该项目自身文档中记载了一个值得提前了解的陷阱,以免到了生产环境才发现:使用近似索引(HNSW 或 IVFFlat)时,过滤条件是在索引扫描之后应用的,而不是之前。如果某个条件只保留 10% 的行,且 hnsw.ef_search 参数采用默认值 40,那么平均只会返回 4 行,而不是请求的 10 行。自 0.8.0 版本起,官方提供了名为迭代索引扫描的解决方案(SET hnsw.iterative_scan = strict_order):它会自动再次执行扫描,直到找到足够多的结果,而不是悄无声息地返回截断的结果集。

!
访问权限不能靠提示词来控制
当多人查询同一索引时,权限过滤机制能防止模型向某个人引用其无权查看的文档。任何提示词指令都不能替代这一过滤机制;基于现有的授权模型,用 SQL 实现这一过滤机制,比重新实现授权逻辑安全得多。

#它的局限

大规模场景下的内存占用
数百万个全精度向量会占用大量内存;halfvec 和二值量化可以减少内存占用,但专用引擎原生支持更高程度的压缩。这是最明显的差距。
索引构建时间
在一张非常大的表上创建HNSW索引耗时较长且资源消耗大;在生产环境中,使用CREATE INDEX CONCURRENTLY构建索引可避免操作期间阻塞写入操作。
资源竞争
将计算负载较重的向量检索与事务负载放在一起,就意味着两者共用同一台服务器。只读副本能有所帮助,而将两者的职责分离效果更好。
向量的维度
索引向量的维度上限取决于其类型(vector 为 2 000 维,halfvec 为 4 000 维)。常见模型都在这一限制内;维度非常高的模型则需要降维或量化。
混合搜索
PostgreSQL 支持全文检索(tsvector),您可以将其与向量距离检索结合使用,但如何让它易于使用,需要您自行实现:必须分别执行两次查询,再合并排序结果,例如使用倒数排名融合(Reciprocal Rank Fusion),而不是通过一次查询直接获得原生混合评分。
横向扩展能力
当扩展到多台服务器时,文档中介绍的方案是使用 PostgreSQL 只读副本,或采用 Citus、PgDog 等分配工具——这意味着要额外增加一个组件,与最初的论点相反。
i
在HNSW索引上执行VACUUM操作可能较慢
官方文档明确指出:对向量索引采用 HNSW 的表执行清理(VACUUM),在数据量很大时可能耗时较长。要加快这一操作,应在 VACUUM 之前执行 REINDEX INDEX CONCURRENTLY,而不是让清理维护操作单独运行——很少有教程会提前提到这一运维细节,往往要等到夜间维护超出预定时间窗口才会发现。

#pgvector 或专用数据库

问题不在于哪一个客观上更好,而在于哪一个更符合您目前的情况。如果 PostgreSQL 已经是应用的权威数据源,存储着计费数据、账户和源文档,pgvector 就更有优势。如果向量数量或查询吞吐量超过了单台事务服务器在不影响应用其他部分的情况下所能承受的范围,专用引擎就更有优势;如果团队出于运维考虑,而非单纯追求性能,希望将 AI 组件与信息系统的其他部分隔离,专用引擎也更有优势。

根据实际情况选择
情况选择
PostgreSQL 已部署,片段数量少于数十万个pgvector,轻松胜任
向量必须与关系型数据保持一致pgvector:交易免费
基于现有权限的精细过滤pgvector
嵌入模型维度超过4000,且不可进行降维处理检查 sparsevec 类型,或专为这种情况设计的数据库
数百万向量,大量查询专用引擎(Qdrant、Milvus)
在交互式笔记本中制作原型任选其一,该选择可随时更改

#FAQ

pgvector 用于 RAG 时,速度够快吗?+
对于典型的本地语料库——几万到几十万个片段——是的,使用 HNSW 索引就足够快;在这一范围的低端,通常甚至不需要索引。检索很少是本地处理流程中缓慢的环节:用户感受到的响应时间主要由模型生成决定。
pgvector 还是 Qdrant?+
如果您已经使用 PostgreSQL,且数据是关系型的,可以选择 pgvector:服务更少,具备事务一致性,支持原生 SQL 过滤,而且只需安排一套备份。如果规模、通过激进量化降低内存占用,或完全针对向量设计的专用服务,比单一数据库的运维简便性更重要,则选择 Qdrant。在向量数量达到数十万个之前,两者都能切实满足同样的需求。
选择哪个索引,HNSW 还是 IVFFlat?+
HNSW 从几个版本前就已成为默认选项:查询性能更好,代价是构建更慢、内存占用更多。IVFFlat 的构建成本较低,但必须先加载具有代表性的数据,再创建索引,否则分区分布会不均匀。
可以按元数据进行过滤吗?+
可以,用普通 SQL 即可,包括连接操作。这是选择它的最佳理由之一,尤其适合按访问权限进行过滤。不过要注意:使用近似索引时,这种过滤会在索引扫描之后执行;如果不使用迭代扫描,返回的结果可能少于预期。
如果更换嵌入模型会怎样?+
所有内容必须重新编码:向量的维度和几何结构属于模型本身,而非数据库。这是在GPU上进行的批量处理,而非模式迁移,且当新维度超过声明值时,必须重新创建列。需预留切换窗口,因为旧索引在重新编码完成前仍有效。
我的嵌入模型维度超过2000,该如何处理?+
标准 vector 类型最多支持为 2,000 维向量建立索引。超过这一维度时,请改用 halfvec 类型(最多 4,000 维,采用半精度),或者在供应商支持的情况下,在生成时降低维度,例如 OpenAI 为 text-embedding-3-large 提供的功能。不建立索引时,PostgreSQL 仍可存储最多 16,000 维的向量,但需要进行精确扫描。
如何诊断向量查询缓慢?+
文档建议在查询语句前加上 EXPLAIN (ANALYZE, BUFFERS),以查看索引是否确实被使用,以及读取了多少个数据块。不使用索引的精确查询可通过增大 max_parallel_workers_per_gather 来提升性能;近似查询速度慢,往往意味着索引仍在构建中,或内存不足以将索引保留在缓存中。
这份指南对您有帮助吗?

有反馈、发现了错误,或想补充说明?请告诉我们,让这份指南对每个人都更有帮助。