Nova 向量检索引擎
Nova 是 AnalyticDB for PostgreSQL 7.0 的向量检索引擎,提供 Nova-Disk(简称 Novad,磁盘型分区索引)和 Nova-Memory(简称 Novam,内存型图索引)两类索引。本文介绍 Nova 的功能特性、索引选型、容量评估、创建与查询方法、参数调优以及运维管理。
功能概述
什么是 Nova
Nova 是 AnalyticDB for PostgreSQL 7.0 内置的高性能向量检索引擎,提供 Novad(磁盘型分区索引)和 Novam(内存型图索引)两类索引。Nova 在查询性能、存储效率和运维便捷性方面进行了深度优化,适用于大规模向量相似度检索场景,如 RAG(检索增强生成)、语义搜索和推荐系统。
核心能力
Nova 面向大规模向量检索,提供以下增强能力:
能力 | 说明 |
自适应搜索 | 在查询速度和召回率之间自动取舍,无需手动调参即可获得良好的检索效果。 |
灵活的存储方案 | Novad 将主要索引数据存储在磁盘,支持 RaBitQ、SQ8、PQ 等量化压缩方式以及 halfvec、bit、sparsevec、sq8vector 等多种向量类型,大幅降低存储成本。 |
Delta-Base 写入架构 | 将数据写入与主索引构建解耦,新数据先写入内存 Delta 文件,后台异步合并到主索引。写入积压时自动触发反压机制,保障系统稳定性。 |
并发创建索引 | 支持 |
INCLUDE 列 | 将额外列存入索引,查询命中这些列时可直接从索引返回结果,减少回表开销。 |
PCA 自动降维 | 支持按方差解释率自动选择目标维度,也支持手动指定维度,有效降低计算量和存储占用。 |
Autotune 自动调参 | 只需指定 topK 和目标召回率,系统自动评估并应用最优搜索参数。支持传入真实查询表进行精细调优,也可基于索引数据生成合成查询。 |
前提条件
AnalyticDB for PostgreSQL 7.0 实例,内核版本为 7.4.2.7 或更高。
快速开始
以下示例演示如何创建表、建立 Nova 索引并执行向量查询。
创建示例表
创建一个包含文本内容和向量列的示例表。
CREATE TABLE chunks (
id SERIAL PRIMARY KEY,
chunk VARCHAR(1024),
intime TIMESTAMP,
url VARCHAR(1024),
feature REAL[]
) DISTRIBUTED BY (id);示例返回
CREATE TABLE创建 Nova 索引
使用默认算法 novamr(带 RaBitQ 量化的内存型索引)创建向量索引。RaBitQ 量化可显著降低内存占用。
-- 使用默认算法 novamr,RaBitQ 量化可显著降低内存占用
CREATE INDEX idx_feature_novamr ON chunks
USING ann(feature)
WITH (
dim = 1536,
distancemeasure = cosine
);示例返回
CREATE INDEXNovamr 当前固定使用 7 bit,不支持自定义 rabitq_bits。
执行向量查询
使用 <=> 运算符计算余弦距离,返回最相似的 10 条结果。
SELECT id,
chunk,
feature <=> ARRAY[0.1, 0.2, ...]::real[] AS distance
FROM chunks
ORDER BY distance
LIMIT 10;示例返回(以实际数据为准)
id | chunk | distance
----+--------------------+----------
12 | Nova 向量检索 | 0.0831
7 | PostgreSQL 检索 | 0.1047
......
31 | 混合检索实践 | 0.1284
(10 rows)索引选型与容量
Novad 与 Novam 对比
Nova 提供 Novad(磁盘型分区索引)和 Novam(内存型图索引)两类索引,适用于不同的业务场景:
Novad(磁盘型分区索引):采用图导航与分区存储相结合的索引结构,少量导航数据驻留内存,主要分区索引数据保存在磁盘。对内存依赖低,索引构建速度快,磁盘占用小,支持 RaBitQ、SQ8 和 PQ 量化。适合大规模数据、成本敏感的检索场景。
Novam(内存型图索引):采用图索引结构。内存充足时,同等规格下查询性能优于 Novad;内存不足时会回退到磁盘访问。支持 RaBitQ、SQ8 和 PQ 量化。适合实时推荐等低延迟场景。

Novam 索引变体
算法名 | 说明 |
| 不带量化压缩的图索引,全精度存储。 |
| 带 RaBitQ 量化的图索引(默认算法,固定使用 7 bit,不支持自定义 |
| 带 SQ8 标量量化的图索引。 |
Novad 索引变体
算法名 | 说明 |
| 带 RaBitQ 量化的分区索引( |
| 不带量化压缩的分区索引。全精度存储,召回率最高。 |
| 带 SQ8 标量量化的分区索引。使用 |
容量评估
以下表格列出不同向量维度和计算资源下的建议数据量上限。实际容量受数据分布、查询模式等因素影响,建议根据业务需求进行压测验证。
Novad 容量参考
总计算资源 | 128 维 | 256 维 | 512 维 | 768 维 | 1024 维 | 1536 维 | 2048 维 |
8c | 320M | 160M | 80M | 50M | 40M | 26M | 20M |
16c | 640M | 320M | 160M | 100M | 80M | 60M | 40M |
32c | 1.28B | 640M | 320M | 200M | 160M | 120M | 80M |
128c | 5.12B | 2.56B | 1.28B | 800M | 640M | 480M | 320M |
Novam 容量参考
总计算资源 | 128 维 | 256 维 | 512 维 | 768 维 | 1024 维 | 1536 维 | 2048 维 |
8c | 32M | 16M | 8M | 5M | 4M | 2.6M | 2M |
16c | 64M | 32M | 16M | 10M | 8M | 5M | 4M |
32c | 128M | 64M | 32M | 20M | 16M | 10M | 8M |
128c | 512M | 256M | 128M | 80M | 64M | 40M | 32M |
向量类型与距离度量
支持的向量类型
Nova 支持多种向量数据类型,覆盖稠密向量、稀疏向量和二值向量等场景。
数据类型 | 说明 | 最大维度 |
| 单精度浮点数组 | 8,000 |
| pgvector 兼容的稠密向量类型 | 8,000 |
| 半精度浮点向量,存储空间约为 | 16,000 |
| 半精度浮点数组 | 16,000 |
| 二值向量,适用于哈希指纹等场景 | 256,000 |
| pgvector 兼容的稀疏向量类型(最大非零元素 4,000) | 1,000,000,000 |
| 稀疏向量类型(最大非零元素 4,000) | 1,000,000,000 |
| SQ8 压缩向量,以 INT8 格式存储,节省内存 | 8,000 |
支持的距离度量
距离度量 | 参数值 | SQL 运算符 | 说明 | 适用向量类型 |
欧氏距离(平方) |
|
| 适用于图片相似度检索 | vector, halfvec, float4[], float2[], int2[], sparsevec, svector, sq8vector |
反内积距离 |
|
| 向量归一化后可替代余弦相似度 | vector, halfvec, float4[], float2[], int2[], sparsevec, svector, sq8vector, bit |
余弦距离 |
|
| 适用于文本相似度检索 | vector, halfvec, float4[], float2[], int2[], sparsevec, svector, sq8vector |
曼哈顿距离 |
|
| L1 距离 | vector, halfvec, sparsevec |
杰卡德距离 |
|
| 适用于集合相似度度量 | bit |
汉明距离 |
|
| 适用于二进制编码相似度 | bit |
特殊向量类型使用示例
halfvec(半精度向量)
halfvec 使用半精度浮点数存储,内存占用约为 vector 的一半,适合对内存敏感的高维向量场景。
-- 创建 halfvec 类型的表
CREATE TABLE chunks_half (
id SERIAL PRIMARY KEY,
feature halfvec(1536)
) DISTRIBUTED BY (id);
-- 创建索引
CREATE INDEX idx_half ON chunks_half
USING ann(feature)
WITH (
dim = 1536,
algorithm = novamr,
distancemeasure = cosine
);sq8vector(SQ8 压缩向量)
sq8vector 以 INT8 格式存储向量,进一步压缩内存。配合 Novam 或 Novad 索引使用。
-- 创建 sq8vector 类型的表
CREATE TABLE chunks_sq8 (
id SERIAL PRIMARY KEY,
feature sq8vector(1536)
) DISTRIBUTED BY (id);
-- 创建 Novam 内存型 SQ8 索引
CREATE INDEX idx_sq8 ON chunks_sq8
USING ann(feature)
WITH (
dim = 1536,
algorithm = novam,
distancemeasure = cosine
);
-- 也可创建 Novad 磁盘型 SQ8 索引
-- sq8vector + novadflat 自动切换为 novadsq8
CREATE INDEX idx_sq8_disk ON chunks_sq8
USING ann(feature)
WITH (
dim = 1536,
algorithm = novadflat,
distancemeasure = cosine
);稀疏向量(svector)
Nova 使用 svector 存储稀疏向量。每个稀疏向量包含两组一一对应的数据:
indices:非零维度的编号(从 0 开始)。values:对应维度的值。
例如,一个 8 维稀疏向量,索引 2、3、6 对应的值分别为 1.2、1.1、0.7,其余位置为 0:
SELECT '{"indices":[2,3,6],"values":[1.2,1.1,0.7]}'::svector(8);示例返回
svector
------------------------------------------------------
{"indices":[2,3,6],"values":[1.2,1.1,0.7]}
(1 row)indices 和 values 的元素数量必须相同,并按位置一一对应。svector(N) 使用从 0 开始的下标,有效范围为 [0, N-1]。例如,svector(8) 的有效下标为 0~7。
创建稀疏向量表示例并创建索引:
DROP TABLE IF EXISTS sparse_docs;
CREATE TABLE sparse_docs (
id BIGINT PRIMARY KEY,
title TEXT NOT NULL,
category TEXT NOT NULL,
publish_at TIMESTAMP NOT NULL,
embedding svector(8) NOT NULL
) DISTRIBUTED BY (id);
INSERT INTO sparse_docs(id, title, category, publish_at, embedding) VALUES
(1, 'PostgreSQL 全文检索', 'search', '2024-01-01',
'{"indices":[1,3,7],"values":[0.8,1.5,0.4]}'),
(2, 'Nova 稀疏向量检索', 'search', '2024-02-01',
'{"indices":[2,3,6],"values":[1.2,1.1,0.7]}'),
(3, '向量数据库实践', 'vector', '2024-03-01',
'{"indices":[1,4,7],"values":[0.9,1.3,1.0]}'),
(4, '数据分析基础', 'analytics', '2024-04-01',
'{"indices":[5,7],"values":[1.4,0.6]}'),
(5, '混合检索方案', 'search', '2024-05-01',
'{"indices":[2,4,6,7],"values":[0.6,1.1,1.2,0.9]}');
-- 使用内积衡量相关性,创建稀疏向量索引
CREATE INDEX sparse_docs_embedding_idx
ON sparse_docs
USING ann (embedding)
WITH (
algorithm = 'novam',
distancemeasure = 'ip'
);
ANALYZE sparse_docs;使用一个 8 维查询向量返回最相关的 3 条数据:
SELECT
id,
title,
category,
-(embedding <#>
'{"indices":[2,3,6],"values":[1,1,0.5]}'::svector(8)
) AS score
FROM sparse_docs
ORDER BY embedding <#>
'{"indices":[2,3,6],"values":[1,1,0.5]}'::svector(8)
LIMIT 3;示例返回
id | title | category | score |
2 | Nova 稀疏向量检索 | search | 2.650 |
1 | PostgreSQL 全文检索 | search | 1.500 |
5 | 混合检索方案 | search | 1.200 |
在上述查询中:
<#>计算负内积。负内积越小,内积越大,相关性越高。ORDER BY embedding <#> 查询向量按相关性从高到低排序,并允许优化器使用 Nova 索引。
二值向量(bit)
bit 类型用于存储二值向量,适用于哈希指纹等场景。支持汉明距离和杰卡德距离。
-- 创建 bit 类型的表
CREATE TABLE chunks_bit (
id SERIAL PRIMARY KEY,
feature bit(256)
) DISTRIBUTED BY (id);
-- 使用汉明距离创建索引
CREATE INDEX idx_bit ON chunks_bit
USING ann(feature)
WITH (
dim = 256,
algorithm = novam,
distancemeasure = hamming
);创建索引
基本语法
CREATE INDEX [CONCURRENTLY] [index_name]
ON [schema_name].[table_name]
USING ann(column_name)
WITH (dim = <dimension>,
algorithm = <algorithm>,
distancemeasure = <measure>,
...);创建 Novad 索引
以下示例创建一个磁盘型 Novad 索引,使用余弦距离度量。
novad 和 novadr 要求向量维度至少为 32;低于 32 维时请使用 novadflat。
CREATE INDEX idx_feature_novad_cosine ON chunks
USING ann(feature)
WITH (
dim = 1536,
algorithm = novad,
distancemeasure = cosine,
nlist = 2048,
accel_m = 32
);创建 Novam 索引
以下示例创建一个内存型 Novam 全精度索引,使用欧氏距离度量。
CREATE INDEX idx_feature_novam_l2 ON chunks
USING ann(feature)
WITH (
dim = 1536,
algorithm = novam,
distancemeasure = l2,
hnsw_m = 32,
hnsw_ef_construction = 200
);并发创建索引
Nova 支持 PostgreSQL 的 CREATE INDEX CONCURRENTLY 语法。创建期间业务可继续读写,避免锁表影响在线服务。
CREATE INDEX CONCURRENTLY idx_chunks_feature_novad
ON chunks
USING ann(feature)
WITH (
dim = 1536,
algorithm = novad,
distancemeasure = cosine,
nlist = 2048
);CREATE INDEX CONCURRENTLY 不能在显式事务块中执行。执行后必须检查 pg_index.indisvalid 和 indisready。如果任一为 false,不要使用该索引;请执行 DROP INDEX index_name 清理后重建。
INCLUDE 列
INCLUDE 可把额外列写入索引,命中这些列时减少回表:
CREATE INDEX [index_name]
ON [schema_name].[table_name]
USING ANN(column_name) INCLUDE (col1, col2, ...)
WITH (dim = <dimension>,
algorithm = <algorithm>,
distancemeasure = <measure>,
...);使用示例
-- 将 id 和 url 列包含在索引中,支持 Index Only Scan 和 Index Scan 不回表
CREATE INDEX idx_feature_include ON chunks
USING ann(feature) INCLUDE (id, url)
WITH (
dim = 1536,
algorithm = novad,
distancemeasure = cosine
);PCA 降维
PCA 降维可在保留主要信息的前提下降低向量维度,减少计算量和存储占用。支持自动和手动两种方式。
pca_dim 与 auto_reduction 不能同时设置:自动降维只设置 auto_reduction,手动降维只设置 pca_dim。
自动选择维度:按方差解释率自动选择目标维度(默认阈值 98%)。
CREATE INDEX idx_pca_auto ON chunks
USING ann(feature)
WITH (
dim = 1536,
algorithm = novamr,
distancemeasure = cosine,
auto_reduction = true
);手动指定维度:通过 pca_dim 指定降维后的目标维度,目标维度需要为64的整数倍。
CREATE INDEX idx_pca ON chunks
USING ann(feature)
WITH (
dim = 1536,
algorithm = novamr,
distancemeasure = cosine,
pca_dim = 256
);索引构建参数
基本参数
参数名 | 说明 | 默认值 | 取值范围 |
| 向量维度(必填,或从列类型自动推断) | 无 | [1, 8192](视向量类型而定) |
| 索引算法 |
| novam, novamflat, novamr, novamsq8, novad, novadflat, novadr, hnswflat |
| 距离度量算法 |
| l2, ip, cosine, l1, jaccard, hamming |
Novam 构建参数
参数名 | 说明 | 默认值 | 取值范围 |
| 图中每个节点的双向连接数。值越大图质量越好,构建时间越长。 | 16 | [2, 100] |
| 构建时搜索候选集大小。值越大图质量越好,构建时间越长。需 ≥ 2 × hnsw_m。 | 64 | [4, 1000] |
| Novamr 固定使用 7 bit,不支持自定义 rabitq_bits | 7 | 不支持配置 |
Novad 构建参数
参数名 | 说明 | 默认值 | 取值范围 |
| 分区索引的聚类列表数 | 1024 | [2, 1073741824] |
| 图导航层中每个中心点的邻居数 | 16 | [8, 1024] |
| 加速层构建候选集大小 | 128 | [1, 32768] |
| RaBitQ 量化比特数(仅 novad/novadr) | 1 | [1, 8] |
PCA 参数
参数名 | 说明 | 默认值 | 取值范围 |
| PCA 降维后的目标维度。0 表示不启用。 | 0 | 需小于原始维度,且为 64 的整数倍 |
| 启用基于方差阈值的自动维度选择,与 | false | true / false |
| 启用 PCA 白化 | false | true / false |
| 启用 PCA 随机旋转 | false | true / false |
系统级构建参数
参数名 | 说明 | 默认值 | 取值范围 |
| 索引构建的最大并行进程数 | 75% 计算节点资源 | [1, 128] |
| 分区索引聚类训练所需的最小向量数 | 100000 | [1, 100000000] |
| K-means 聚类迭代次数 | 10 | [0, 100000] |
查询与调优
参数优先级
Nova 搜索参数可以配置在两个位置:
配置方式 | 生效范围 | 有效期 |
会话级 GUC | 当前数据库连接中的查询 | 连接断开后失效 |
索引级 Reloption | 使用指定索引的查询 | 持续生效,直到重新设置或 RESET |
Reloption 与会话 GUC 的对应关系如下:
索引级 Reloption | 对应的会话级 GUC | 适用索引 |
|
| Novam |
|
| Novam |
|
| Novad |
|
| Novam、Novad |
查询时按以下规则取值:
索引 Reloption 状态 | 实际使用的参数 |
设置了具体值 | 使用索引 Reloption |
未设置、已 RESET 或值为 -1 | 使用对应的会话 GUC |
一句话概括:会话级 GUC 是当前连接的默认值;索引级 Reloption 可以为指定索引覆盖这个默认值。
例如,会话 GUC 为 80,某个索引的 Reloption 为 200:
查询使用的索引 | 实际使用值 |
设置了 Reloption 的索引 | 200 |
其他未设置 Reloption 的索引 | 80 |
-1 只表示继承会话 GUC,不是实际搜索值。
会话级查询参数
使用 SET fastann.<参数名> = <值>; 配置当前会话。若索引支持同名 reloption,则只有该 reloption 为 -1 或已 RESET 时才会使用会话值。
Novam 查询参数
参数名 | 说明 | 默认值 | 取值范围 |
| 图搜索时的动态候选集大小。最关键的 Novam 调优参数,值越大召回率越高,查询越慢。 | 100 | [1, 1000] |
| 稀疏向量搜索的 ef_search | 200 | [1, 1000] |
| 图搜索最大扫描点数 | 2000 | [0, 10000000] |
| 量化索引(SQ/RaBitQ)的重排候选集放大倍数 | 1.0 | [0.0, 1000.0] |
Novad 查询参数
参数名 | 说明 | 默认值 | 取值范围 |
| 分区索引搜索时探测的聚类列表数。最关键的 Novad 调优参数,值越大召回率越高,I/O 越多。 | 5 | [1, 100000] |
| 加速层查询时的 ef_search | 128 | [1, 32768] |
| 结果堆放大倍数 | 1.0 | [1.0, 1000.0] |
| RaBitQ 量化的重排放大倍数 | 1.0 | [0.0, 1000.0] |
通用查询参数
参数名 | 说明 | 默认值 | 取值范围 |
| 混合查询(向量 + 过滤条件)的 topK 放大倍数 | 10 | [1, 1000] |
| 计算节点 topK 乘数因子。计算节点 topK = topK × mul + add | 1.0 | [0.0, 1000.0] |
| 计算节点 topK 加数因子 | 0.0 | [0.0, 1000.0] |
索引级查询参数
当某个具体索引需要使用不同于会话默认值的搜索参数时,可为该索引设置 reloptions。其中索引级(reloption)查询参数 = -1 表示使用对应的会话级(GUC)查询参数。
Reloption | 适用索引 | 继承的 GUC | 默认值 | 取值范围 |
| Novam |
| -1 | -1 或 [1, 1000] |
| Novam |
| -1 | -1 或 [0, 10000000] 范围内 500 的整数倍 |
| Novad |
| -1 | -1 或 [1, 100000] |
| Novam、Novad |
| -1 | -1 或 [0.0, 1000.0] |
| Novam、Novad | 无 | 0 | 0 或 [1, 1000] |
| Novam、Novad | 无 | 0 | 0 或 [0.90, 0.99] |
nova_autotune_topk 和 nova_autotune_recall 必须成对设置,用于记录或切换 Autotune 配置。详细用法请参见Autotune 自动调参。
设置索引级参数
-- 固定 Novam 索引的搜索参数
ALTER INDEX idx_feature_novam_l2 SET (
nova_ef_search = 200,
nova_max_scan_points = 5000
);
-- 固定 Novad 索引的搜索参数
ALTER INDEX idx_feature_novad_cosine SET (
nova_nprobe = 20
);恢复继承会话 GUC
-- Novam 索引恢复继承会话 GUC
ALTER INDEX idx_feature_novam_l2
RESET (nova_ef_search, nova_max_scan_points);
-- Novad 索引恢复继承会话 GUC
ALTER INDEX idx_feature_novad_cosine
RESET (nova_nprobe);配置示例
使用索引 reloptions 固定单个索引的搜索参数:
-- 固定 Novam 索引参数
ALTER INDEX idx_feature_novam_l2 SET (
nova_ef_search = 200,
nova_max_scan_points = 5000
);
-- 固定 Novad 索引参数
ALTER INDEX idx_feature_novad_cosine SET (
nova_nprobe = 20
);reloption 为 -1 或已 RESET 时,查询改用当前会话 GUC:
ALTER INDEX idx_feature_novam_l2
RESET (nova_ef_search, nova_max_scan_points);
SET fastann.hnsw_ef_search = 200;
SET fastann.hnsw_max_scan_points = 5000;Autotune 自动调参
Autotune 可自动调优 Novam 和 Novad 的搜索参数。只需指定 topK 和目标召回率,系统会自动评估并应用最优参数配置。支持传入真实查询表进行精细调优,也支持基于索引数据生成合成查询。
调优任务异步执行,调用后立即返回 handle。传入多个 topK 或 target_recall 时,系统会评估全部组合。任务完成后,自动将索引的搜索参数设置为最大 topK、最大 target_recall 对应的配置。
启动调优
以下示例同时调优 topK = 10 和 100,目标召回率为 0.99。传入测试查询表 docs_eval_queries,可保证在该查询集上达到目标召回率。每个 topK 和 target_recall 组合分别保存一套配置;任务完成后,索引自动应用最大组合,即 topK = 100、target_recall = 0.99。
SELECT *
FROM fastann.nova_autotune(
index_relation => 'public.docs_embedding_novam_idx'::regclass, -- 必填;无默认值;作用:指定待调优索引
topk => ARRAY[10, 100], -- 必填;无默认值;作用:指定需要调优的 topK
target_recall => 0.99, -- 可选;默认值:0.99;作用:指定目标召回率
n_samples => 100, -- 可选;默认值:300;作用:指定采样查询数
n_trials => 100, -- 可选;默认值:500;作用:指定候选配置试验数
query_table => 'public.docs_eval_queries'::regclass, -- 可选;默认值:NULL;作用:指定测试查询表
query_column => 'embedding' -- 可选;默认值:NULL;作用:指定查询向量列
) AS result(handle);没有测试查询表时,省略 query_table 和 query_column。系统会根据索引内部数据生成查询并拟合参数:
SELECT *
FROM fastann.nova_autotune(
index_relation => 'public.docs_embedding_novam_idx'::regclass, -- 必填;无默认值;作用:指定待调优索引
topk => ARRAY[10, 100], -- 必填;无默认值;作用:指定需要调优的 topK
target_recall => 0.99, -- 可选;默认值:0.99;作用:指定目标召回率
n_samples => 100, -- 可选;默认值:300;作用:指定采样查询数
n_trials => 100 -- 可选;默认值:500;作用:指定候选配置试验数
) AS result(handle);示例返回
handle
-----------
123456790
(1 row)不传入 query_table 时,Autotune 不能保证实际查询的召回率。需要召回率保证时,应传入有代表性的查询表。
查看调优进度
使用 nova_autotune 返回的 handle 查看任务进度:
SELECT
stage,
query_count,
work_done,
work_total,
updated_at
FROM fastann.nova_autotune_progress(
handle => 123456789
);示例返回
stage | query_count | work_done | work_total | updated_at
------------+-------------+-----------+------------+------------------------
evaluating | 300 | 126 | 500 | 2026-07-28 14:20:42+08
(1 row)work_done / work_total 表示任务进度百分比。进度函数返回 0 行时,表示任务已结束或 handle 已不在活动状态,不代表调优失败;此时可通过 nova_autotune_status 查看已筛选的配置,并回读索引 Reloption。
手动切换参数配置
Autotune 会保存每组 topK 和 target_recall 对应的参数。查看索引已有的全部调优结果:
SELECT
topk, target_recall, achieved, autotune_recall,
ef_search, max_scan_points, nprobe, rescore_amp, applied
FROM fastann.nova_autotune_status(
index_relation => 'public.docs_embedding_novam_idx'::regclass
)
ORDER BY topk, target_recall;示例返回
topk | target_recall | achieved | autotune_recall | ef_search | max_scan_points | nprobe | rescore_amp | applied
------+---------------+----------+-----------------+-----------+-----------------+--------+-------------+---------
10 | 0.99 | t | 0.992 | 80 | 3000 | 0 | 1.2 | f
100 | 0.99 | t | 0.991 | 240 | 12000 | 0 | 1.5 | t
(2 rows)每组 topK 和 target_recall 对应一套参数配置,切换时必须同时指定两者:
-- 使用 topK=10 时达到 99% 召回率的配置
ALTER INDEX public.docs_embedding_novam_idx SET (
nova_autotune_topk = 10,
nova_autotune_recall = 0.99
);
-- 切换到 topK=100 时达到 99% 召回率的配置
ALTER INDEX public.docs_embedding_novam_idx SET (
nova_autotune_topk = 100,
nova_autotune_recall = 0.99
);一个索引同时只能运行一个 Autotune 任务。
Score Filter
Score Filter 在 ANN 扫描阶段按相似度或距离阈值淘汰候选,减少后续排序和返回的数据量。可通过 GUC 或 SQL Hint 启用。
参数名 | 说明 | 默认值 |
| 启用或禁用 Score Filter | 禁用 |
| 最小 Score 阈值 | -3.40282e+38 |
| 最大 Score 阈值 | 3.40282e+38 |
通过 SET 启用
下面的查询只返回余弦相似度大于 0.75 的 topK 结果:
SET fastann_score_filter_switch = on;
SET fastann_score_filter_min = 0.75;
RESET fastann_score_filter_max;
SELECT id,
chunk,
1 - (
feature <=> ARRAY[0.1, 0.2, ...]::real[]
) AS score
FROM chunks
ORDER BY score
LIMIT 10;示例返回(以实际数据为准)
SET
SET
RESET
id | chunk | score
----+--------------------+-------
12 | Nova 向量检索 | 0.921
7 | PostgreSQL 检索 | 0.884
(2 rows)需要限定分数区间时,同时设置上下限:
SET fastann_score_filter_switch = on;
SET fastann_score_filter_min = 0.75;
SET fastann_score_filter_max = 0.95;通过 SQL Hint 启用
Hint 必须放在一次独立 SQL 调用的最前面,前面不要拼接 SET、RESET 或其他语句。设计上只影响当前语句;使用前请在同一连接中验证当前版本是否会影响后续查询。
/*+ SET(fastann_score_filter_switch on)
SET(fastann_score_filter_min 0.75)
SET(fastann_score_filter_max 0.95) */
SELECT id,
chunk,
1 - (
feature <=> ARRAY[0.1, 0.2, ...]::real[]
) AS score
FROM chunks
ORDER BY score
LIMIT 10;示例返回(以实际数据为准)
id | chunk | score
----+--------------------+-------
12 | Nova 向量检索 | 0.921
7 | PostgreSQL 检索 | 0.884
(2 rows)写入与运维
Delta-Base 写入架构
Nova 使用 Delta-Base 架构接收实时写入,将数据写入与主索引构建解耦:
新向量先写入内存映射的 Delta 文件,最多同时存在 3 个。
每个 Delta 文件最多保存
max_delta_vecs个向量(默认约 100 万)。后台 Flush 线程定期将 Delta 数据合并到主索引。
可调用
nova_flush_index()手动触发合并。可调用
nova_delta_stats()查看 Delta 文件状态。
写入反压
当 Delta 文件接近容量上限时,系统自动限制写入速度,防止内存溢出。
参数名 | 说明 | 默认值 |
| 启用写入反压 | true |
| 软限阈值(Delta 填充比),超过后开始添加延迟 | 0.1 |
| 软限最小延迟(毫秒) | 5 |
| 软限最大延迟(毫秒) | 15 |
| 硬限阈值(Delta 填充比),超过后阻塞写入 | 0.3 |
| 硬限最大等待时间(毫秒) | 1000 |
索引统计信息
-- 查看索引统计信息
SELECT nova_stats(
index_oid => 'idx_feature_novamr'::regclass::oid, -- 必填;无默认值;作用:指定 Nova 索引 OID
metadata_only => true -- 可选;默认值:true;作用:是否只返回静态元数据
);
-- 查看 Delta 文件状态
SELECT *
FROM nova_delta_stats(
'idx_feature_novamr'::regclass -- 必填;无默认值;作用:指定要查看的 Nova 索引
);示例返回(节选,数值以实际索引为准)
nova_stats
--------------------------------------------------
{
"metadata": {
"dimensions": 1536,
"metric_kind": "cosine",
...
}
}
(1 row)
gp_segment_id | index_name | delta_index | vectors | fullness
---------------+-----------------------+-------------+---------+----------
0 | idx_feature_novamr | {0,1} | {120,0} | {0.12,0}
1 | idx_feature_novamr | {0,1} | {98,0} | {0.10,0}
(2 rows)手动 Flush
手动触发 Delta 数据合并到主索引:
SELECT *
FROM nova_flush_index(
index_relation => 'idx_feature_novamr'::regclass
);示例返回
gp_segment_id | success
---------------+---------
0 | t
1 | t
(2 rows)REINDEX
使用标准 PostgreSQL REINDEX 命令重建 Nova 索引:
REINDEX INDEX CONCURRENTLY idx_feature_novamr;示例返回
REINDEX兼容性与限制
pgvector 兼容模式
pgvector 兼容模式提供 pgvector 0.8.2 的常用类型、运算符、索引语法和参数名。索引由 Nova 构建和查询,并非原生 pgvector 索引。兼容层与 USING ann 可在同一数据库中并存。
启用兼容模式
当前版本使用 pgvector 兼容模式前,请提交工单申请开通。开通完成后,普通用户即可创建和使用 pgvector 兼容索引。
如需使 <-> 返回与 pgvector 一致的欧氏距离,请在会话中设置 fastann.pgvector_compatibility = on;仅用于 TopK 排序且不读取距离值或按距离过滤时,无需设置。
索引语法与 Nova 后端
可直接使用 pgvector 索引语法,距离度量由运算符类确定:
CREATE INDEX docs_embedding_hnsw_idx
ON docs USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
CREATE INDEX docs_embedding_ivfflat_idx
ON docs USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 1024);pgvector 语法 | 支持的列类型 | Nova 后端 |
| vector、halfvec |
|
| bit、sparsevec |
|
| vector、halfvec | 维度 ≥ 32 时使用 |
hnsw 和 ivfflat 是 pgvector 兼容语法名称。Nova 兼容其建索引和查询接口,实际索引由 Nova 后端实现,不等同于原生 HNSW 或 IVFFlat。pgvector 兼容访问方法和运算符类共同决定 Nova 后端及距离度量;即使同时指定 algorithm 或 distancemeasure,也不会改变后端选择规则。
支持的运算符类
访问方法 | 列类型 | 支持的运算符类 |
|
| vector_l2_ops、vector_ip_ops、vector_cosine_ops |
|
| halfvec_l2_ops、halfvec_ip_ops、halfvec_cosine_ops |
|
| sparsevec_l2_ops、sparsevec_ip_ops |
|
| bit_hamming_ops、bit_jaccard_ops |
|
| vector_l2_ops、vector_ip_ops、vector_cosine_ops |
|
| halfvec_l2_ops、halfvec_ip_ops、halfvec_cosine_ops |
参数映射
pgvector 参数 | Nova 参数 | 默认值 | 说明 |
|
| 16 | 图索引节点最大邻居数,取值范围 2~100 |
|
| 64 | 构建候选集大小,取值范围 4~1000,且不小于 2 × m |
|
| 1024 | 分区索引聚类数,取值范围 2~1073741824 |
|
| 100 | 两个名称引用同一会话参数,取值范围 1~1000 |
兼容 IVFFlat 查询通过 nova_nprobe 调整搜索范围;未设置时继承 fastann.nova_nprobe,默认值为 5。ivfflat.probes 和 fastann.ivfflat_probes 对该兼容索引不生效。
限制
不支持在 Nova 索引上使用 L1 运算符类。创建
vector_l1_ops或halfvec_l1_ops索引会报错。sparsevec的余弦运算符类暂不支持 Nova 索引。余弦检索需要将索引向量和查询向量归一化后按内积搜索,当前 Nova 构建链路尚未接通稀疏向量的归一化处理。请使用 L2 或内积替代。ivfflat仅支持vector和halfvec的 L2、内积和余弦距离。pgvector 语法映射到 Nova 后端,索引结构、量化方式、存储占用、召回率和性能特征与原生 pgvector 不完全相同。
svector最多支持 10 亿维,最多包含 4,000 个非零值。indices和values必须包含相同数量的元素。values必须是有限数值,不能包含NaN、Infinity或-Infinity。
使用注意事项
Nova 会在后台执行 Delta 合并和图修复。即使没有业务请求,也可能占用系统资源。在资源规划时请考虑此因素。