EN

pgvector 教程 2026:PostgreSQL 中的向量相似性搜索

无需额外基础设施,为 PostgreSQL 数据库添加语义搜索以支持 RAG

返回教程列表🌐 Read in English
进阶11 分钟

pgvector 教程 2026:PostgreSQL 中的向量相似性搜索

无需额外基础设施,为 PostgreSQL 数据库添加语义搜索以支持 RAG

pgvector 教程(2026 年):在现有 PostgreSQL 上执行向量搜索——HNSW 与 IVFFlat 选择、操作符对齐、完整 Python 流水线、SQL 过滤与混合搜索(专用向量数据库的付费功能在此仅是一个查询)、内存估算及迁移阈值。

pgvector 教程 2026:PostgreSQL 中的向量搜索用于 RAG

pgvector 为 PostgreSQL 添加了向量相似性搜索——这意味着你的 RAG 应用可以将文档、元数据*和*嵌入向量保存在你已经在运行的同一个数据库中,SQL 连接和过滤与最近邻搜索自然组合。对于大多数拥有数百万向量以下的团队来说,这是一个正确的起点:一个备份方案、一个事务模型、零新基础设施。

安装

bash

最简单:官方 Docker 镜像

docker run -d -e POSTGRES_PASSWORD=pass -p 5432:5432 pgvector/pgvector:pg17

sql
CREATE EXTENSION vector;

托管 Postgres(Supabase、Neon、RDS、Cloud SQL)都支持 pgvector——通常只需执行 CREATE EXTENSION

模式与索引

sql
CREATE TABLE documents (
    id BIGSERIAL PRIMARY KEY,
    content TEXT NOT NULL,
    metadata JSONB DEFAULT '{}',
    embedding vector(1536),          -- 必须与你的嵌入模型维度匹配
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- HNSW 索引:最佳查询性能,2026 年的默认选择 CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);

重要的索引决策:

  • HNSW vs IVFFlat:HNSW 提供更好的召回率/速度,并且不需要在索引构建时存在训练数据;IVFFlat 构建更快且使用更少内存,但需要调优(lists),并且随着数据漂移而性能下降。除非构建时间/内存是真正的限制,否则默认使用 HNSW。
  • 操作符类必须与查询操作符匹配vector_cosine_ops<=>(余弦距离),vector_l2_ops<->vector_ip_ops<#>。对于归一化嵌入(OpenAI 的),余弦和内积排序相同——选择余弦并保持一致。
  • 查询时召回率旋钮SET hnsw.ef_search = 100;(默认 40)——值越高,召回率越好,查询越慢。
  • Python 完整流水线

    python
    import psycopg
    from openai import OpenAI

    ai = OpenAI() conn = psycopg.connect('postgresql://postgres:pass@localhost/postgres')

    def embed(texts: list[str]) -> list[list[float]]: resp = ai.embeddings.create(model='text-embedding-3-small', input=texts) return [d.embedding for d in resp.data]

    导入(批量调用嵌入——每个块一次 API 调用是经典的浪费)

    chunks = ['pgvector supports HNSW indexes...', 'Cosine distance is...'] vectors = embed(chunks) with conn.cursor() as cur: for text, vec in zip(chunks, vectors): cur.execute( 'INSERT INTO documents (content, embedding) VALUES (%s, %s)', (text, str(vec)) ) conn.commit()

    查询

    def search(question: str, k: int = 5): qvec = embed([question])[0] with conn.cursor() as cur: cur.execute(''' SELECT content, metadata, embedding <=> %s::vector AS distance FROM documents ORDER BY distance LIMIT %s ''', (str(qvec), k)) return cur.fetchall()

    pgvector 的独特之处:SQL 的组合能力

    与专用向量数据库相比,杀手级功能不是速度——而是向量搜索只是真实 SQL 中的一个子句:

    sql
    -- 过滤搜索:仅该租户最近 90 天的文档
    SELECT content, embedding <=> $1 AS distance
    FROM documents
    WHERE metadata->>'tenant_id' = $2
      AND created_at > NOW() - INTERVAL '90 days'
    ORDER BY distance
    LIMIT 10;
    

    一个微妙之处:对于选择性非常高的过滤器,规划器可能会扫描 HNSW 索引并丢弃大部分候选(“后过滤”),从而损害召回率。pgvector 0.8+ 添加了迭代索引扫描,持续获取直到满足 LIMIT——升级后这类问题基本消失。对于大规模硬租户隔离,每个租户的局部索引或分区是更重的手段。

    混合搜索(向量 + 关键词)也只是 SQL——结合 tsvector 全文搜索并融合排名(CTE 中的倒数排名融合)。这是专用存储作为高级功能销售的功能;在这里只是一个查询。检索质量方面——分块、重排序、评估——在语义搜索实现中介绍。

    生产注意事项

  • 内存:HNSW 索引常驻 RAM 以获得速度——一百万个 1536 维 float32 向量大约需要 6 GB 原始向量加上索引开销;相应调整实例大小,或使用 pgvector 0.7+ 中的 halfvec(float16,内存减半,检索质量损失可忽略)。
  • 维度:较小的嵌入模型(或 Matryoshka 截断的模型)线性减少内存和速度——768 维通常足够;在你自己的数据上基准测试召回率。
  • 批量插入:对于大量导入使用 COPY;在批量加载*之后*构建 HNSW 索引,而不是之前。
  • Django/ORM 集成:一流支持——参见我们的 Django AI 集成指南中的 pgvector 部分。
  • 何时迁移到专用向量数据库

    诚实的阈值:数千万向量且严格的 p99 延迟、非常高写入吞吐量且并发搜索、或检索作为核心产品需要 GPU 加速索引。然后比较 Qdrant vs ChromaPinecone vs Weaviate。低于这些阈值,pgvector 的操作简单性通常胜出——并且后续迁移是机械的(导出向量,重新索引)。

    常见问题

    能否将不同模型的嵌入存储在同一张表中? 不同维度需要不同的列(或表)。使用新模型重新嵌入所有内容几乎总是比混合更清晰。

    pgvector 是否支持重排序? 不支持——在应用程序代码中(交叉编码器或 LLM)对 pgvector 返回的前 50 个候选进行重排序。数据库的工作是快速候选检索。

    事务支持? 是的——这正是重点。原子性地插入文档行、其块和嵌入;无需在数据库和单独的向量存储之间进行双写一致性协调。


    *最后更新:2026 年 6 月。*

    相关工具

    postgresqlopenaipython
    所属主题:RAG 检索增强生成