一句话定义
pgvector 是 PostgreSQL 的开源扩展:给表加 vector 列、建 HNSW 或 IVFFlat 索引、用 SQL 完成"相似度排序 + 任意 WHERE 过滤 + JOIN 事务"——把向量检索装进最成熟的关系数据库生态。
为什么重要
pgvector 是"关系库扩展"谱系的旗手,也是选型讨论的起点:如果数据已在 PostgreSQL、量级在千万级以内、过滤逻辑复杂,它的综合成本几乎必然最低。它的天花板(索引维度上限、单机写扩展、大表索引构建时长)同样清晰——知道边界与知道优势同样重要。
前置知识
kp-007(IVF 参数——lists/probes 的原型)、kp-008(HNSW 参数——m/ef 的原型)、kp-018(谱系定位)。
核心概念
- vector 类型:定长浮点数组列;另有 halfvec(半精度)、bit(二进制量化)、sparsevec(稀疏)等家族类型(版本演进中)。
- HNSW 索引:
USING hnsw (embedding vector_cosine_ops),参数 m、ef_construction;查询时SET hnsw.ef_search。 - IVFFlat 索引:
USING ivfflat (embedding vector_cosine_ops) WITH (lists=N),查询时SET ivfflat.probes,即 kp-007 的 nlist/nprobe。 - 度量操作符类:
vector_l2_ops/vector_ip_ops/vector_cosine_ops,建索引时绑定,对应 kp-003 的三种度量。 - 执行计划风险:规划器可能判断"过滤选择率低"而放弃索引扫描、退化顺序扫描——这是 pgvector 过滤场景的头号故障。
原理与机制
最小可用路径(可执行步骤):
CREATE EXTENSION vector;
CREATE TABLE docs (id bigserial PRIMARY KEY, body text,
embedding vector(1024), tenant_id int, created_at timestamptz);
-- 建索引(二选一):
CREATE INDEX ON docs USING hnsw (embedding vector_cosine_ops) WITH (m=16, ef_construction=64);
CREATE INDEX ON docs USING ivfflat (embedding vector_cosine_ops) WITH (lists=1000);
-- 查询(先在会话里调在线参数):
SET hnsw.ef_search = 100; -- 或 SET ivfflat.probes = 20;
SELECT id, body FROM docs
WHERE tenant_id = 42 AND created_at > now() - interval '30 days'
ORDER BY embedding <=> $1 LIMIT 10; -- <=> 余弦距离, <-> L2, <#> 内积关键机制与约束:
- 索引维度上限:普通 vector 列的 HNSW/IVFFlat 索引只支持约 2000 维(halfvec 提高上限),超高维模型需先降维或用 halfvec。
- 索引不在建表时自动生效:先灌数再建索引(IVFFlat 还要求建索引时表里有数据供聚类)。
- 过滤走组合执行:WHERE 条件与向量排序联合优化;当规划器估计过滤后行数很少时可能选择位图扫描甚至顺序扫描,用
EXPLAIN ANALYZE确认是否走了索引。 - 更新的代价:HNSW 索引随高频 UPDATE/DELETE 退化,需要 REINDEX 周期;大表 REINDEX 以小时计。
- 扩展手段:halfvec 降内存、分区表按租户/时间分区、只读副本分担查询。
公式或模型
本节不适用:产品实操篇,参数语义继承自 kp-007/008 的公式体系。
图示
SQL 查询 ─► 规划器 ─┬─ 走向量索引(HNSW/IVFFlat) + 位图过滤 ✔ 快
└─ 估计过滤后行数过少 → 顺序扫描全表 ✘ 秒级灾难
EXPLAIN ANALYZE 是确认走哪条路的唯一方式实例或案例
SaaS 文档助手:业务数据本在 PostgreSQL(用户、权限、文档元数据),新增 embedding 列 + HNSW 索引即可支持语义搜索,权限过滤直接复用既有 WHERE org_id=… AND visibility=…,与业务表 JOIN 拼装答案上下文,备份/审计/高可用全部沿用 RDS 现状——零新增系统。当文档量增长到 2 亿、p99 逼近 200 毫秒时,迁移信号出现:考虑 halfvec 量化、分区,或迁往专用向量库(kp-027 决策树 Q1 分支)。
直观类比
pgvector 是给家用轿车(PostgreSQL)加装行李架(向量索引):日常购物完全够用、不需要再买货车;但要每周搬十吨货(亿级、高并发向量负载),就该换卡车而不是无限加固轿车。
常见误区
- "pgvector 性能天然不如专用库"——同参数同硬件下 HNSW 检索速度差距不大;真正差距在超大库建索引时长、高频写退化、分布式能力,不是单点查询。
- "加了 WHERE 就自动高效过滤"——规划器可能放弃向量索引;过滤场景必须 EXPLAIN 验证,必要时用 CTE +
ORDER BY embedding的写法或分区引导执行计划。 - "probes/lists 可以随便改"——lists 建库后改动需重建索引;probes 是会话级在线参数,但必须在同会话/连接池内生效(连接池复用会"丢"SET,需在事务或连接初始化里设置)。
自测题
- 一条语义查询莫名变成秒级,第一步做什么?
- 使用 3072 维嵌入模型直接建 pgvector 索引会遇到什么?
- 连接池环境下
SET hnsw.ef_search为什么会"失效"?
答:EXPLAIN ANALYZE 看执行计划——大概率规划器放弃向量索引走了顺序扫描;对策:检查过滤选择率、调整统计信息、改写查询或分区。
答:超过索引维度上限(普通 vector 约 2000 维);先截断/Matryoshka 降维,或改用 halfvec 类型,或换支持高维的引擎。
答:SET 是会话级的,连接归还池后可能被其他请求复用;应在事务内设置,或把参数写进连接初始化语句,确保每次取用的连接都带参数。
与其他知识点的关系
kp-007/008 是其两类索引的原理原型;kp-021 的单机专用库是它的对照方案;kp-027 决策树中"数据已在 PG"分支直达本篇。
延伸阅读
pgvector 官方项目文档(开源项目,参数与类型随版本演进)——以最新文档核对索引参数与维度上限;本库仅陈述原理与经验区间。