pgvector 是 PostgreSQL 的向量检索扩展,让你不用额外引入 Chroma、Milvus 这类专用向量数据库,就能用早已熟悉的关系型数据库完成 Embedding 存储与相似度搜索。本文从安装到生产落地,手把手带你在 PostgreSQL 上跑通向量检索,并接进 RAG 知识库。
一、为什么要用 pgvector,而不是再装一个向量库
做 RAG(检索增强生成)时,最核心的一步是把文本切成片段、转成向量(Embedding),再按语义相似度找出最相关的几段。pgvector 的价值在于:你团队里大概率已经有一套稳定运行的 PostgreSQL,为什么还要为「向量」单独养一个组件?多一个向量库,就意味着多一套部署、备份、监控和权限体系。pgvector 以扩展形式寄生在已有 PG 里,运维成本几乎为零。
当然它并非银弹:超大规模(十亿级向量)场景专用向量库仍有优势。但对绝大多数中小型知识库、企业内部检索、原型验证来说,pgvector 的性价比极高。关于 RAG 召回的进阶玩法,可参考我们之前的《大模型 RAG 进阶:混合检索与重排序优化实战》。
要诚实地说,pgvector 不是万能锤。当向量规模冲到十亿级、或需要极致写入吞吐与多副本分片时,专用向量库(如 Milvus、Qdrant)仍有优势。但这类场景在中小企业和大多数产品早期根本碰不到——别为想象中的规模提前买单,先用好手里的 PostgreSQL 才是务实选择。
二、环境准备与扩展安装
pgvector 要求 PostgreSQL 12 及以上,推荐 14+。索引方面,0.5 版本起支持 HNSW 近似索引,查询性能比早期 IVFFlat 好很多。最常见的安装方式是用官方镜像或包管理器,下面以 Docker 为例:
# 直接使用带 pgvector 的 PostgreSQL 镜像
docker run -d --name pgvector \
-e POSTGRES_PASSWORD=yourpassword \
-p 5432:5432 \
ankane/pgvector:latest
# 进入数据库后启用扩展
docker exec -it pgvector psql -U postgres -c "CREATE EXTENSION IF NOT EXISTS vector;"
若你是自建 PG,Debian/Ubuntu 可直接 apt install postgresql-16-pgvector,再执行上面的 CREATE EXTENSION。安装后可用 SELECT vector_version(); 确认版本。
三、定义向量列与基础表结构
向量在 pgvector 里是一种新数据类型 vector(n),n 是维度,必须提前固定,且全表所有向量维度须一致(例如 OpenAI text-embedding-3-small 是 1536 维,bge-m3 是 1024 维)。
CREATE TABLE documents (
id BIGSERIAL PRIMARY KEY,
content TEXT, -- 原始文本
embedding vector(1536), -- 1536 维向量
created_at TIMESTAMPTZ DEFAULT now()
);
-- 插入一条:直接用方括号写法表示向量
INSERT INTO documents (content, embedding)
VALUES (
'PostgreSQL 是最流行的开源关系型数据库',
'[0.12, -0.03, 0.88, ... , 0.21]' -- 实际应填入 1536 个浮点数
);
四、写入 Embedding 与相似度计算
pgvector 提供三种距离运算符,对应不同相似度定义:<-> 是欧氏距离(L2),<#> 是负内积,<=> 是余弦距离。一般语义检索用余弦距离最稳妥。下面的 SQL 找出与给定问题向量最相似的 5 条:
-- :query_vec 为问题文本的 1536 维向量
SELECT id, content, embedding <=> :query_vec AS distance
FROM documents
ORDER BY embedding <=> :query_vec
LIMIT 5;
距离越小越相似,排序后取 Top-K 即可作为上下文喂给大模型。这一步的召回质量是否够好,建议用《向量检索评测实战:Recall@K 与 RAG 质量度量》里的方法量化。
实战提醒:送入 Embedding 的文本最好先做好切块与清洗——去重、去噪、控制单段长度在模型 token 上限内。否则向量质量上不去,召回再快也是 garbage in garbage out。切块策略(按段落、按固定字数、按语义边界)本身也会显著影响 RAG 最终效果,值得单独调优。
五、给向量列加索引:IVFFlat 与 HNSW
没有索引时,相似度查询是全表扫描,数据量大了会非常慢。pgvector 支持两种索引,选型差异明显:
| 维度 | IVFFlat | HNSW |
|---|---|---|
| 查询精度 | 近似,召回略低 | 近似,召回更高 |
| 查询速度 | 快 | 极快 |
| 构建成本 | 低,需先采样 lists | 较高,写入变慢 |
| 适用规模 | 百万级以下 | 百万到亿级 |
新项目无脑选 HNSW 即可,语法如下:
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops);
-- 注意:HNSW 索引需在有一定数据后创建,
-- 并适当调大构建内存以避免落盘变慢
SET maintenance_work_mem = '2GB';
5.1 HNSW 关键参数调优
HNSW 有两个常用调优参数:m 控制每个节点的连接数(默认 16,越大召回越高但越占内存),ef_construction 控制建索引时的搜索宽度(默认 64,越大索引质量越高、构建越慢)。数据量不大时默认值已够用,追求极致召回再逐步上调:
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
六、把它接进 RAG:一个最小可运行示例
下面用 Python(psycopg + OpenAI 兼容接口)演示「入库 + 检索」闭环,其余 LLM 调用部分可套用《2026 年搭建私有 AI 知识库:Dify + Ollama 本地部署》的架构。
import openai, psycopg
from pgvector.psycopg import register_vector
client = openai.OpenAI(base_url="https://your-endpoint/v1", api_key="sk-xxx")
conn = psycopg.connect("dbname=postgres user=postgres password=xxx")
register_vector(conn)
def embed(text):
r = client.embeddings.create(model="text-embedding-3-small", input=text)
return r.data[0].embedding
# 入库
with conn.cursor() as cur:
cur.execute("INSERT INTO documents(content, embedding) VALUES (%s, %s)",
("pgvector 让 PG 支持向量检索", embed("pgvector 让 PG 支持向量检索")))
conn.commit()
# 检索 Top-5
q = embed("PostgreSQL 怎么做语义搜索?")
with conn.cursor() as cur:
cur.execute("SELECT content FROM documents ORDER BY embedding <=> %s LIMIT 5", (q,))
for row in cur.fetchall():
print(row[0])
七、生产落地注意事项
1. 索引构建时机。 空表上直接建 HNSW 索引,写入会明显变慢。建议先灌入全量数据,再建索引;之后的增量写入影响可控。
2. 查询计划与性能。 向量检索慢时,先确认是否真的走了索引(EXPLAIN 看是否出现 Index Scan)。PG 的慢查询排查套路与本站《PostgreSQL 慢查询优化:执行计划解读与索引调优》一致,核心都是读懂执行计划。
3. 维度统一与迁移。 一旦表定下 1536 维,后续换 Embedding 模型就要重建列,早期规划好很重要。若你已在用独立向量库,可参考《Chroma 向量数据库实战》对比两者的取舍。
4. 混合检索。 纯向量召回容易漏掉关键词精确匹配,线上往往把向量检索与全文检索(tsvector)结合,这正是高质量 RAG 的标配。
5. 备份与容灾。 好消息是 pgvector 的向量就存在普通表里,你既有的 PG 备份方案(逻辑 dump 或 PITR)天然能覆盖它,无需额外操心。具体做法可直接复用《PostgreSQL 备份与 PITR 时间点恢复实战》里的脚本。
八、小结
pgvector 用极低的接入成本,把「向量检索」这一 RAG 关键能力塞进了你本来就有的 PostgreSQL。落地清单:① 选 PG 14+ 并装扩展;② 固定向量维度建表;③ 用余弦距离做相似度;④ 数据就绪后建 HNSW 索引;⑤ Python 侧入库+检索闭环;⑥ 配合混合检索与评测持续优化。当你不想为向量再养一套系统时,pgvector 就是那把最顺手的锤子。




