这篇适合谁,读完能做到什么
适合已经在用 Postgres、想给自己的内容加上语义检索(按意思而不是按原字搜索)的开发者。读完你应该能装好 pgvector,选出合适的向量类型和距离运算符,建一个 HNSW 索引,并看懂我们为 TellWorld 问答功能搭的这套配置,包括怎样避免对没有改动的文本重复向量化。
pgvector 是什么
pgvector 是一个扩展,给 Postgres 加上了向量类型和最近邻搜索。它提供 vector、halfvec、bit 和 sparsevec 几种类型。halfvec 存半精度元素,占用 2 * dimensions + 8 字节,vector 则是 4 * dimensions + 8 字节;两者都支持最多 16,000 维。[2]
默认情况下,pgvector 做的是精确的最近邻搜索,召回率是完美的。加上 HNSW 或 IVFFlat 这类近似索引,就是用一部分召回率换速度。[2]HNSW 索引会建立一张多层图。它的查询性能比 IVFFlat 好,代价是建索引更慢、占用内存更多。它不需要训练步骤,所以可以在没有数据时就创建。[2]我们用的是 HNSW。
距离运算符有好几种。<-> 是 L2 距离,<#> 是负内积,<=> 是余弦距离,<+> 是 L1 距离,<~> 是二值向量的汉明距离,<%> 是二值向量的 Jaccard 距离。README 说明,<#> 返回的是负内积,因为 Postgres 的索引扫描只支持 ASC 排序。[2]
准备
README 给出的是从源码编译安装的方式,版本是 v0.8.7。Linux 和 Mac 的源码安装支持 Postgres 13+。[2]CHANGELOG 列出的最新正式版是 0.8.7 (2026-10-01),下一个版本 0.9.0 尚未发布。[3]安装时要固定版本,升级之前先看一下 CHANGELOG。
用 Docker 的话,镜像 pgvector/pgvector:pg18-trixie 会在官方 Postgres 镜像上加入 pgvector。[2]用 Homebrew 装的 Postgres 则执行 brew install pgvector,它只会加到 postgresql@18 和 postgresql@17 两个 formula 上。[2]README 还列出了 PGXN 的 pgxn install vector、APT 的 sudo apt install postgresql-18-pgvector、Yum 的 sudo yum install pgvector_18、APK 的 apk add postgresql-pgvector,以及 conda-forge 的 conda install -c conda-forge pgvector。[2]
向量化我们用的是阿里云百炼(Alibaba Cloud Model Studio)。它的 text-embedding-v4 是一个多语言文本向量模型,由 Qwen3 训练而来,支持 64 到 2048 之间的自定义维度。[4]北京地域的限流是 RPM 1800、TPM 1,200,000。[4]该模型按输入 token 计费,输出不计费。[6]北京地域的输入单价是每百万 token 0.5 元,Batch 调用半价,另有 100 万 token 的免费额度,有效期 90 天。[5][6]
上手步骤
- 从源码安装 pgvector。README 给出的命令是:[2]
cd /tmp
git clone --branch v0.8.7 https://github.com/pgvector/pgvector.git
cd pgvector
make
make install # may need sudo- 在每个要用到它的数据库里执行一次
CREATE EXTENSION vector;启用扩展。[2]
- 建 HNSW 索引。README 的示例在一张叫
items的表上,写法是CREATE INDEX ON items USING hnsw (embedding vector_l2_ops);。m和ef_construction默认分别是16和64,可以用WITH (m = 16, ef_construction = 64)设置。[2]HNSW 索引按距离函数分别创建。README 还列出了vector_ip_ops、vector_cosine_ops、vector_l1_ops、bit_hamming_ops和bit_jaccard_ops,并说halfvec应使用halfvec_l2_ops。[2]我们用的是halfvec_cosine_ops,查询时对应的运算符是<=>。[2]
- 查询时用距离运算符做升序的
ORDER BY,并加上LIMIT。查询必须同时具备这两者,索引才会被使用。[2]搜索的候选列表由hnsw.ef_search控制,默认值是40。用SET LOCAL可以只对当前事务生效:[2]
BEGIN;
SET LOCAL hnsw.ef_search = 100;
SELECT ...
COMMIT;- 确定向量维度和批量大小。
text-embedding-v4默认1024维;北京地域的表格列出的可选维度有2,048、1,536、1,024、768、512、256、128和64。[5]批次大小是10,即一次请求最多向量化 10 段文本,每段不超过8192个 token。[5]北京地域单批次最多处理33,000个 token,新加坡地域则是8,192。[5]
- 把客户端指向兼容 OpenAI 的端点。北京的
base_url是https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1,新加坡地域是https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1。密钥从环境变量DASHSCOPE_API_KEY读取。[5]
我们的做法
TellWorld 的每个条目都会被切成若干分块,存进 cms_chunk 表。每一行包含文本、token 数、内容哈希、模型名和向量。[1]向量列是 halfvec(1024),用 halfvec_cosine_ops 建 HNSW 索引。[1]1024 与 text-embedding-v4 的默认维度一致。[5]同一张表上还有一个基于文本的 trigram GIN 索引(gin_trgm_ops),用于关键词匹配。[1]
向量来自兼容 OpenAI 的 /embeddings 端点,默认模型是 text-embedding-v4。[1]我们只对内容有改动的分块重新向量化,能做到这一点,靠的就是内容哈希。2026 年 11 月 13 日的一次运行涉及 5,342 篇文档、34,228 个分块,其中只重新向量化了 94 个分块,用了 7,531 个 token。[1]网站的问答功能就是从这些分块中检索的。[1]
每一行都记录模型名,在更换模型时就能分辨每个向量是哪个模型生成的。[1]这是我们针对自己内容做的设计。分块数量和 token 消耗都来自我们自己的运行,别的站点看到的数字会不同。
限制和常见问题
- 使用近似索引时,过滤条件是在索引扫描之后才应用的。如果某个条件只匹配 10% 的行,那么在 HNSW 和默认的
hnsw.ef_search为 40 的情况下,平均只会有大约 4 行被匹配。[2] - 对于 HNSW,如果过滤条件去掉了太多候选,查询返回的行数可能少于你要求的数量。README 介绍了迭代索引扫描(
0.8.0引入),用SET hnsw.iterative_scan = strict_order;开启。[2] - README 建议在生产环境使用
CREATE INDEX CONCURRENTLY,以免阻塞写入。[2] NULL向量不会被索引;对余弦距离来说,零向量也不会被索引。[2]- HNSW 的限制是:
vector最多2,000维,halfvec最多4,000维,bit最多64,000维,sparsevec最多1,000个非零元素。[2] - 另一种索引是 IVFFlat。应在表里已有数据之后再创建。
lists在 100 万行以内取rows / 1000,超过 100 万行取sqrt(rows);probes从sqrt(lists)开始调。README 用SET ivfflat.probes = 10;设置 probes。[2] - 批量调用的向量化费用是实时调用的一半,但批次的限制依然适用。官方文档建议,对于大规模的非实时文本,用
text-embedding-v4配合兼容 OpenAI 的 Batch 调用,可显著降低成本。[5] - 我们的
1024维和halfvec的4,000维上限相比,都在 HNSW 的限制之内。[2]
下一步
先读 pgvector 的 README[2]和 CHANGELOG。[3]再读阿里云百炼的向量化文档[5]和计费页面。[6]正式上线前,先对一小批文档完整跑一遍重新向量化,把 token 数与计费页面对一下。
来源
- 1
- 2pgvector README (master)pgvector (official GitHub repository)
- 3pgvector CHANGELOG (master)pgvector (official GitHub repository)
- 4text-embedding-v4 模型信息阿里云百炼 (Alibaba Cloud Model Studio)
- 5向量化(Embedding)阿里云百炼 (Alibaba Cloud Model Studio)
- 6模型计费 (billing-for-model-studio)阿里云百炼 (Alibaba Cloud Model Studio)
引用本页: 用 Postgres 和 pgvector 做语义检索. TellWorld, https://www.tellworld.net/zh/practice/practice-pgvector-search. 更新于 2026-11-14