☰
pg_vectorsearch 火了,但 RAG 先补上 pgvector 的 3 个坑
2026/10/18 20:48:33 网站建设 项目流程

这两天 Hacker News 前排被 Timescale 新发的 PostgreSQL 向量检索扩展 pg_vectorsearch 占了一块。它主打一个 PRISM 索引,官方说在 1 亿向量上建索引只要 49 分钟,而 pgvector 的 HNSW 要 42 小时,查询延迟还能砍一半。数字很炸,但发布帖写得很清楚:这是 alpha,要求 PostgreSQL 18+,只能测试、不能上生产。对绝大多数还在跑 pgvector 0.5/0.6、PostgreSQL 14~16 的 RAG 服务来说,眼前能落地的不是换引擎,而是先把 pgvector 用对。下面三个坑,是调向量检索延迟时最高频的问题。

热点背景:PRISM 到底快在哪

pg_vectorsearch 是 Timescale(原 TimescaleDB 团队)在 2026-10-13 开源的 PostgreSQL 扩展,状态明确标着 alpha。它新增的索引访问方法叫 PRISM(Partitioned Routing Index for Similarity Matching)。结构上是 IVF 风格:用一棵层次质心树把向量分区,查询时只路由到最近的几个簇;向量用 RaBitQ 量化压缩成约每维 1 bit,并带理论误差界,先用压缩码粗筛、再用全精度向量重排;距离计算走 SIMD(AVX2 / AVX512 / NEON)。

官方自测里最抢眼的一组数(来源 Timescale 发布帖,厂商口径,需打折扣看):同一台 64 vCPU、512 GiB 的机器,1 亿条 Cohere 向量,HNSW 建索引 42 小时、索引占 180 GB;PRISM 建索引 49 分钟、索引占 25 GB,p50 查询延迟约为 HNSW 的一半。它还能直接建在已有的 pgvector 列上——vec32/vec16 与 vector/halfvec 二进制兼容,不改表、不改查询。代价是必须 PostgreSQL 18 以上,且目前只是 alpha,跨预发版不保证能平滑升级。

换句话说:值得盯着,但现在别急着动生产库。先把手里已经跑着的 pgvector 调明白,性价比最高。

索引类型建索引特点内存占用现阶段适用
IVFFlat单遍扫描、建时锁表低小表 / 只读分析
HNSW快、不阻塞写入高大表 / 高频写入
PRISM(alpha)官方自测 49min/1 亿低未来生产候选,当前仅测试

环境准备

想复现下面的坑,最快是起一个带 pgvector 的 PostgreSQL 容器,再用 Python 连上去跑 EXPLAIN 看执行计划:

docker run -d --name pg -e POSTGRES_PASSWORD=postgres -p 5432:5432 ankane/pgvector:pg17 pip install "pgvector[psycopg]" numpy

坑一:忘了 SET ivfflat_probes,索引等于白建

pgvector 的 IVFFlat 索引靠ivfflat_probes控制查询时扫描的聚类数,默认值只有 1。也就是你建了索引、查询也走 Index Scan,但每次只翻 1 个 list,召回率会悄悄掉到很低,你还以为"索引生效了"。下面这段脚本在同一张表上对比 probes=1 和 probes=20 的执行计划,跑出来你会看到 probes=1 时只扫了 1 个 list:

import os import numpy as np import psycopg from pgvector.psycopg import register_vector DSN = os.getenv("PG_DSN", "postgresql://postgres:postgres@localhost:5432/postgres") conn = psycopg.connect(DSN) register_vector(conn) conn.execute("CREATE EXTENSION IF NOT EXISTS vector") conn.execute("DROP TABLE IF EXISTS docs") conn.execute("CREATE TABLE docs (id int PRIMARY KEY, emb vector(128))") rows = [(i, np.random.randn(128).astype("float32")) for i in range(5000)] with conn.cursor() as cur: cur.executemany("INSERT INTO docs (id, emb) VALUES (%s, %s)", rows) conn.commit() conn.execute("CREATE INDEX ON docs USING ivfflat (emb vector_l2_ops) WITH (lists = 70)") # lists ≈ sqrt(行数) q = np.random.randn(128).astype("float32") def plan(probes): conn.execute(f"SET ivfflat_probes = {probes}") out = conn.execute( "EXPLAIN ANALYZE SELECT id FROM docs ORDER BY emb <-> %s LIMIT 10", [q] ).fetchall() return "\n".join(r[0] for r in out) print("=== probes=1(默认)===") print(plan(1)) print("\n=== probes=20 ===") print(plan(20)) conn.close()

跑出来会看到:probes=1 时是Index Scan但只扫了 1 个 list;把 probes 调到 20,扫描的 list 数上来,召回才接近暴力检索。生产环境一般把ivfflat_probes设成 lists 的几分之一到全部,再按 EXPLAIN 输出里的Lists行确认。

坑二:表太小或 lists 配错,planner 直接走 Seq Scan

IVFFlat 不是银弹。表行数太少(pgvector 经验上低于约 1000 行),或者lists设得离谱,优化器会认为顺序扫描更便宜,于是你辛辛苦苦建的索引根本不被用。一个常见反模式是给小表也硬上 IVFFlat,还纳闷为什么延迟没降。

lists的经验起点是sqrt(行数),数据量涨了要重建索引才能改 lists。更麻烦的是 IVFFlat 建索引是单遍、会拿表锁,大数据量上线期间建索引会阻塞写入。这也是为什么 pgvector 0.5 之后官方更推荐USING hnsw:HNSW 建索引快、支持并行、不阻塞写入,代价是内存占用更高。简单说,小表 / 只读分析用 IVFFlat 够用,大表高频写入优先 HNSW:

CREATE INDEX ON docs USING hnsw (emb vector_l2_ops);

坑三:cosine 距离没归一化,召回率偷偷掉

用余弦相似度时,pgvector 的vector_cosine_ops并不会替你把向量归一化。如果原始向量模长不齐,cosine 实际上会被模长偏置,召回结果和"真正语义最近"对不上。插入前先归一化是最稳的做法:

def normalize(v): n = np.linalg.norm(v) return v / n if n > 0 else v emb = normalize(np.random.randn(128).astype("float32")) conn.execute("INSERT INTO docs (id, emb) VALUES (%s, %s)", [1, emb])

L2 距离(vector_l2_ops)没有这个问题,但很多 RAG 场景用的就是 cosine,这条最容易漏。顺带提一句,上面看到的 PRISM 也提供vec32_cosine_ops,它同样依赖你喂进去的是归一化向量才能拿到发布帖里那档召回率:

-- 需要 PostgreSQL 18+ 且安装 alpha 版 pg_vectorsearch CREATE EXTENSION pg_vectorsearch; CREATE INDEX documents_embedding_prism ON documents USING prism (embedding vec32_cosine_ops); SET prism.nprobe = 40; -- 0 = 自动,约 0.95 召回 SELECT * FROM documents ORDER BY embedding '[3,1,2]' LIMIT 5;

小结

pg_vectorsearch 的 PRISM 把"Postgres 里做亿级向量检索"的门槛又往下拉了一截,49 分钟建 1 亿向量确实亮眼,但 alpha + PG18 的门槛意味着它短期进不了生产。对正在跑 pgvector 的服务,先把ivfflat_probes、索引类型选型、向量归一化这三件事核对一遍,往往能直接把查询延迟和召回率拉回预期,比急着换引擎实在。等它脱离 alpha、PG18 普及,再评估迁移也不迟。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询