Aurabase 的本机矢量搜索(RAG、pgvector、嵌入)依赖于相同的索引机制,在 Postgres 上的 Native AI页面上详细描述。本指南假设 Postgres 表已安装 pgvector、类型为 vector的列以及至少几千行。下面,简单的顺序扫描通常比近似索引更快。
要点
- 与 IVFFlat 不同,HNSW 不需要任何训练阶段:索引是通过插入构建的,自 0.5.0 版本起在 pgvector 中可用。
- 有两个参数设置构造时索引的质量:
m(每个节点的连接数,默认 16)和ef_construction(构造时的搜索宽度,默认 64)。 - 第三个参数
hnsw.ef_search(pgvector 默认值:40)针对每个请求进行调整,无需重建索引,以仲裁召回和延迟。 - pgvector 将
vector类型的 HNSW 索引上限限制为 2000 个维度。除此之外(例如,具有 3072 维的嵌入),需要强制转换为halfvec才能建立索引。 - pgvector 0.8.6 是嵌入 Aurabase Postgres 租户映像中的版本,于 2026 年 8 月 24 日直接在 Dockerfile 中验证。
pgvector 中的 HNSW 索引是什么?
HNSW 代表分层可导航小世界。它是一个图索引:每个向量成为连接到其最近邻居的节点,组织在几个叠加层中。搜索从图的顶部最稀疏的层开始,然后逐层向下到最相关的邻居。因此,搜索时间几乎是对数的,而不是与行数呈线性关系。
IVFFlat 是 pgvector 的另一个索引,其工作方式有所不同:它将向量空间划分为由现有样本的训练过程确定的列表,然后才能对任何内容进行索引。 HNSW没有这个约束,每次插入都直接丰富了图,这使得对连续增长的表进行操作变得更简单。另一方面,与相同卷上的等效 IVFFlat 相比,HNSW 索引消耗更多内存并且需要更多时间来构建。
pgvector 在 0.5.0 版本中引入了 HNSW 支持。更高版本为本指南添加了有用的功能:halfvec 类型 (0.7.0) 用于索引超过 2000 个维度,以及 hnsw.iterative_scan 参数 (0.8.0) 用于提高筛选查询的召回率。如果您在决定之前将 pgvector 与专用向量库进行比较,我们的 比较 pgvector 与 Pinecone、Weaviate 和 Qdrant 详细说明了权衡。
创建索引之前检查您的 pgvector 版本
首先确认安装的pgvector版本。太旧的扩展会导致本指南中的某些功能无提示地失败,特别是 halfvec 和 hnsw.iterative_scan。
HNSW 自 pgvector 0.5.0 起就存在。 halfvec类型是索引超过 2000 个维度的嵌入所必需的,至少需要 0.7.0 版本。 hnsw.iterative_scan 参数请求版本 0.8.0。
在 Aurabase 项目上,不会出现这个问题:Postgres 映像嵌入 pgvector 0.8.6,既在共享 Postgres 集群(docker/Postgres.Dockerfile,直接构建于 pgvector/pgvector:0.8.6-pg16-bookworm)上,又在每个项目专用的 Postgres 16 CNPG 实例上(docker/Postgres.CNPG.Dockerfile,继承了官方的 pgvector 0.8.6 ) CloudNativePG 图像)。已于 2026 年 8 月 24 日在两个 Dockerfile 中进行验证。
根据嵌入的大小选择正确的列类型
列类型取决于嵌入的大小,而不仅仅是生成它们的模型。 pgvector 以 vector类型存储经典向量,存储空间上限为 16,000 维。但此类型的 HNSW 索引仅限于 2000 个维度:超出此范围,CREATE INDEX 会失败。
常见的嵌入模型通常会超过此阈值:来自 OpenAI 的 text-embedding-3-large 或来自 Google 的 gemini-embedding-2 本身可生成高达 3072 维的数据。要使用 HNSW 索引这些向量,请将列转换为 halfvec (存储精度减半),这将索引限制远远超出 2000 维。
| 尺寸 | 专栏 | 向量上的 HNSW | 需要铸造 |
|---|---|---|---|
| 768 | 嵌入_768 | 是的 | 否 |
| 1536 | 嵌入_1536 | 是的 | 否 |
| 3072 | 嵌入_3072 | 否(> 2000 暗淡) | 是的,演员::halfvec(3072) |
Aurabase RAG 引擎说明了生产中的这种妥协:支持三类维度(768、1536、3072),存储在同一 embeddings表的三个不同列中。列 768 和 1536 直接在 HNSW 中以 vector类型进行索引。列 3072 通过 ::halfvec(3072)转换进行索引,精确地规避 2000 维上限。
For details of ingestion (chunking, call to the embedding provider, insertion), see the RAG pipeline tutorial on pgvector.
使用 m 和 ef_construction 参数创建索引
对于第一个索引,使用 pgvector 的默认值,最小语法就足够了。
pgvector 然后应用 m = 16 和 ef_construction = 64。要显式调整这些值,请使用 WITH 子句:
在大表上构建 HNSW 索引之前,暂时增加会话的 maintenance_work_mem :根据 pgvector 文档本身,这是减少构建时间的最直接手段。
参数m改变了什么?
m 设置图中每个节点每层维护的最大连接数。较高的值会使图形更加稠密:召回率增加,但消耗的内存和构建时间也会增加,近似线性。默认值 (16) 适用于大多数情况。在大型嵌入中,达到 24 或 32 尤其合理,因为近邻和远邻之间的区别会变得更精细。
ef_construction 改变了什么?
ef_construction 设置索引构建期间为每个插入节点探索的候选列表的大小。较高的值可以提高最终图表的质量,从而提高潜在的召回率,但代价是较长的构建时间。与 m不同,此参数在查询时没有成本:它是一次性投资,仅在创建索引时支付一次。
同一个表中多个维度类的部分索引
当表存储多个向量列(每个维度类一个,如 Aurabase 那样)时,请使用 WHERE colonne IS NOT NULL子句单独为每列建立索引。这种部分索引避免了为给定行未使用的类建立空行索引,从而减少了索引的大小并加快了其构建速度,而无需任何召回成本。
运算符类(vector_cosine_ops、 vector_l2_ops 或 vector_ip_ops)的选择必须与训练嵌入模型的指标相对应。最近的文本嵌入模型都针对余弦相似性进行了训练:因此,vector_cosine_ops(或强制转换列上的 halfvec_cosine_ops)是最安全的默认选择。
在查询时设置 ef_search
ef_search 在每个查询上设置,而不是在构建索引时设置。它设置搜索过程中探索的候选列表的大小:它越高,召回率就越好,但代价是延迟更长。 pgvector 将其默认值设置为 40。
一旦查询将向量搜索与扫描索引(在命名空间、租户或任何其他元数据标准上)后应用的 WHERE 过滤器结合起来,40 就远远不够了。 HNSW 扫描带回 ef_search 原始候选者,然后过滤器丢弃其中的一部分。如果幸存下来的候选者太少,最终的 LIMIT 最终会出现填充不足的情况。
因此,Aurabase RAG 引擎根据请求的 top_k动态扩展 ef_search ,而不是保留固定值 40: ef = max(top_k × 4, 64)。使用 ef_search = 64搜索 5 个最接近的结果;搜索前 50 名使用 ef_search = 200。对于需要另一个召回/延迟权衡的部署,此公式仍然可以根据环境变量进行调整。
pgvector 0.8 针对同一问题添加了第二个杠杆: hnsw.iterative_scan。在 strict_order 或 relaxed_order模式下,搜索逐渐扩大其搜索范围,直到过滤后收集到足够的结果,而不是停在固定的候选列表上。 Aurabase 默认在 strict_order中激活它,但在保存点中保护调用。在 0.8 之前的 pgvector 版本中,如果不存在此参数,则查询会继续以降级模式而不是失败。
构建完整的 RAG 管道
这个 HNSW 索引只是完整 RAG 管道的一部分:分块、嵌入生成、摄取,然后搜索。我们的 分步教程 在 pgvector 上端到端构建此管道,从第一次插入到相似性查询。 技术文档 还详细介绍了 Aurabase 在 Postgres 上构建的所有本机 AI 功能。