×
技术社区 >  技术博客 >  OceanBase 向量索引创建之前如何估算内存占用大小?

OceanBase 向量索引创建之前如何估算内存占用大小?

1. 背景说明

OceanBase 从 4.3.5 版本开始支持向量检索,可通过向量索引(如 HNSW、IVF 系列)加速近似最近邻(ANN)搜索。向量索引属于内存密集型结构:索引数据在提供服务期间需常驻内存,构建过程中还存在额外的峰值内存开销。

4.3.5 BP3 版本对向量内存管理做了调整:ob_vector_memory_limit_percentage 的默认行为从“默认关闭”改为“自适应模式”,系统会根据租户实际内存大小自动决定向量索引的内存占比。但在数据量较大或维度较高的场景下,仍可能出现7603: Vector index memory usage exceeds user defined limit 错误。因此在容量规划阶段对向量索引的内存需求进行估算,仍是必要步骤。

INDEX_VECTOR_MEMORY_ADVISOR 用于在不访问实际业务数据的情况下,基于用户输入的预期向量规模和索引参数,快速估算索引内存占用。该函数从 4.3.5 BP3 版本开始提供。

2. 功能概述

离线估算:不读取表数据,不执行 CREATE INDEX,仅基于入参计算。

仅输出建议值:结果用于容量规划,不作为建索引时的内存门禁,不会因估算超限而报错或阻止 DDL。

支持分区模拟:通过 max_tablet_vectors 参数指定最胖分区的规模。

返回示例:


-- 仅一项(HNSW / HNSW_SQ / HGRAPH)
Suggested minimum vector memory is 7.2 GB


-- 两项(HNSW_BQ、IVF 系列)
Suggested minimum vector memory is 4.1 GB, memory consumption when providing search service is 347.5 MB

返回的建议值对应串行创建索引时的最大内存需求。创建 HNSW_BQ 索引时,系统会视内存情况自动选择并行或串行方式;若内存仅刚好满足建议值,可能因无法并行创建而增加构建耗时。

3. 语法与参数

3.1 函数签名


FUNCTION INDEX_VECTOR_MEMORY_ADVISOR(
    idx_type           VARCHAR(65535),          -- 索引类型
    num_vectors        BIGINT UNSIGNED,         -- 预期全表向量条数
    dim_count          INT UNSIGNED,            -- 向量维度
    dim_type           VARCHAR(65535) DEFAULT 'FLOAT32',  -- 元素类型
    idx_parameters     LONGTEXT DEFAULT NULL,   -- 索引参数字符串
    max_tablet_vectors BIGINT UNSIGNED DEFAULT 0 -- 单 tablet 最大向量行数
)

3.3 max_tablet_vectors 与分区模拟

引擎通过下式计算分区数:

tablet_count = ceil(num_vectors / max_tablet_vectors)

  • 数据均匀分布时,max_tablet_vectorsceil(总行数 / 分区数)
  • 存在数据倾斜时,应取最大分区的行数。

函数本身不感知实际分区定义或数据分布,需调用方根据实际情况指定。

3.4 参数默认值

idx_parameters 中未显式指定的参数将按以下默认值补全:

参数 HNSW 系 IVF 系
M 16 —(IVF_PQ 中为子空间数)
EF_CONSTRUCTION 200
EF_SEARCH 64
NLIST 128
SAMPLE_PER_NLIST 256
NBITS 8

idx_parameters 中包含 EXTRA_INFO_ACTUAL_SIZE 且类型为 HNSW,解析后算法类型会标记为 HGRAPH,估算逻辑与 HNSW 相同。

4. HNSW 系列估算

适用于 HNSWHNSW_SQHNSW_BQHGRAPH

4.1 估算方法

HNSW 系列内存估算调用 OceanBase 自研向量索引库 VSAG 的 EstimateMemory(N) 接口。VSAG 通过 SIMD 加速、高效内存布局及量化等技术实现了高性能 ANN 搜索,估算精度取决于 VSAG 内部模型。

4.2 M 参数的内部变换

用户传入的 M 与 VSAG 实际使用的 max_degree 并不直接对应:

  • HNSW_SQ:调用 EstimateMemory 前,M 被调整为 max(M/2, 8)
  • HNSW_SQ / HNSW_BQ / HGRAPH:在创建索引时 max_degree 会再乘以 2。

同一 M 值在不同索引类型下可能得到不同的内存估算结果。

4.3 HNSW / HNSW_SQ / HGRAPH

进行两次 VSAG 估算,相加后乘以安全系数 1.2:

Suggested = ceil( (Estimate(N_total) + Estimate(N_tablet_max)) × 1.2 )

  • N_total = num_vectors
  • N_tablet_max = max_tablet_vectors
  • 非分区表时两次 N 相同,结果为 2 × Estimate(N) × 1.2,高于单次全表估算。

仅返回一项:Suggested minimum vector memory

4.4 HNSW_BQ

HNSW_BQ 基于 RaBitQ 量化算法,可大幅降低内存占用(官方数据最高约 95%)。估算时区分构建态与检索态,并额外计入 refine 向量存储:

service = ceil( Estimate(N_total, is_build=false) × 1.2 )

build = Estimate(N_tablet_max, is_build=true) -- 含 refine 向量

Suggested = service + ceil(build × 1.2)

返回两项(不可相加):

返回字段 变量 含义
Suggested minimum vector memory Suggested 构建与检索的峰值内存,已含检索稳态占用
memory consumption when providing search service service 索引建成后的检索稳定内存占用

4.5 参数对估算的影响

参数 是否影响 说明
num_vectorsdim_countM、距离类型 直接影响图规模及边属性
EF_CONSTRUCTION、索引类型(SQ/BQ) 通过 VSAG 创建参数影响
EF_SEARCH 极小 视 VSAG 内部实现而定,通常可忽略
REFINE_K 未传入 VSAG
REFINE_TYPEBQ_BITS_QUERYBQ_USE_FHT 可能
EXTRA_INFO_ACTUAL_SIZE 触发 HGRAPH 时须显式指定,否则按普通 HNSW 处理

5. IVF 系列估算

适用于 IVF_FLATIVF_SQ8IVF_PQ

5.1 计算方式

IVF 系列不使用 VSAG,采样如下公式计算,以最胖分区行数 N = max_tablet_vectors 为基准。

5.2 IVF_FLAT / IVF_SQ8 公式

中间量:

nlist = min(N, NLIST)
sample_cnt = min(N, SAMPLE_PER_NLIST × nlist)

核心部分:

buff_mem = 4 × nlist × dim
construct_mem = 1000 + 2×nlist×(nlist+1) + 8×nlist×dim + 4×sample_cnt×(dim+2)

  • buff_mem:检索阶段常驻的聚类中心及倒排列表缓存。
  • construct_mem:索引构建期间的临时内存(KMeans 训练、样本缓存等)。

IVF_FLAT 与 IVF_SQ8 共用同一公式,SQ8 量化节省的内存在 ADVISOR 中未体现。

5.3 IVF_PQ 的特殊处理

IVF_PQ 在 IVF 基础上增加 PQ 码本及子空间 KMeans 估算:

  • construct_mem = max(ivf_construct, pq_construct)
  • 距离类型为 L2 时,buff_mem 包含额外距离表项。

5.4 分区组合

多分区时,buff_mem 按分区数线性累加,construct_mem 只计一次:

Service = buff_mem × tablet_count
Suggested minimum = construct_mem + Service

返回两项(不可相加):

返回字段 含义
Suggested minimum vector memory 构建峰值 + 所有分区的检索缓存
memory consumption when providing search service buff_mem × tablet_count,检索稳态占用

差值 Suggested - Service = construct_mem,对应构建阶段额外开销。

6. 与建索引内部校验的差异

ADVISOR 与 CREATE INDEX 时的内部校验使用不同的安全系数和计算口径,结果不可等同。

对比维度 ADVISOR 建索引内部校验
HNSW 估算调用 两次 Estimate(全表 + 最胖分区) 单次 Estimate(row_count)is_build=true
HNSW 安全系数 ×1.2 ×2.0(VEC_ESTIMATE_MEMORY_FACTOR)×1.2 = ×2.4
IVF 计算范围 construct_mem + buff_mem × tablet_count construct_mem(不含检索缓存)
是否校验上限 是,与租户向量内存上限比较,不满足则拒绝建索引
是否读取视图 读取 __all_virtual_tenant_vector_mem_info

从差异可见:

  • ADVISOR 显示“够用”不等于建索引一定成功(内部校验安全系数更高)。
  • ADVISOR 显示“偏大”也不代表建索引一定失败(IVF 场景下 ADVISOR 的 Suggested minimum 可能因包含检索缓存而更大)。

7.ob_vector_memory_limit_percentage 的版本变化

自 4.3.5 BP3 版本起,ob_vector_memory_limit_percentage 的默认行为变更:

版本 默认行为
V4.3.5 BP3 之前 默认 0,不为向量索引分配内存
V4.3.5 BP3 及之后 自适应模式,系统自动调整占比

自适应规则:

  • 租户实际内存 ≤ 8GB:自动设为 40%
  • 租户实际内存 > 8GB:自动设为 50%

配置项取值范围为 [0, 100),实际最大值受 memstore_limit_percentage 约束:实际最大值 = 85 - MemStore 占比。设置后立即生效,无需重启 OBServer。

如需扩大向量索引内存占比,可先降低 _memstore_limit_percentage,但可能对 DML 性能产生影响。

8. 局限性与适用场景

8.1 估算模型局限

  • HNSW 依赖 VSAG 内部模型,估算在一定程度存在偏差。
  • IVF 使用简化公式,并行 KMeans 时 thread_cnt 固定为 1,多线程构建的峰值可能被低估;硬编码安全系数 1.5 不可配置。
  • 增量写入、SNAP 合并、辅助表等运行时开销未完全纳入估算。

8.2 分区模型局限

HNSW 的 Estimate(全表) + Estimate(最胖分区) 与运行时每 tablet 一个 VSAG 实例的部署方式不完全等价,多分区场景下估算可能存在偏差。

8.3 适用场景

适用 不适用
建表前对比不同索引类型与参数的内存量级 替代建索引或灌数后的实际内存观测
评估维度、数据量变化的内存趋势 精确的 SLA 容量保证
非分区表的粗略估算 召回率、延迟等性能评估
判断是否需要调大 ob_vector_memory_limit_percentage 未指定 EXTRA_INFO_ACTUAL_SIZE 的 HGRAPH 场景

8.4 使用建议

  • 分区表按最胖分区设置 max_tablet_vectors,而非平均值。
  • 可通过 ADVISOR 对比不同 MNLIST 对内存的量级影响。
  • 由于内部校验安全系数更高(HNSW ×2.4),规划内存时可在 ADVISOR 建议值基础上额外预留 20%~50% 余量。
  • 索引创建或数据导入后,通过系统视图查询实际内存占用。

9. 以500W记录的评估示例

9.1 非分区 HNSW


SELECT DBMS_VECTOR.INDEX_VECTOR_MEMORY_ADVISOR(
  'HNSW',
  5000000,
  768,
  'FLOAT32',
  'M=10,DISTANCE=L2',
  0
);

输出建议信息如下:
Suggested minimum vector memory is 36.5 GB

9.2 HNSW_BQ


SELECT DBMS_VECTOR.INDEX_VECTOR_MEMORY_ADVISOR(
  'HNSW_BQ',
  5000000,
  768,
  'FLOAT32',
  'M=10,DISTANCE=L2'
);

输出建议信息如下:
Suggested minimum vector memory is 20.5 GB, memory consumption when providing search service is 1.7 GB

9.3 IVF_FLAT


SELECT DBMS_VECTOR.INDEX_VECTOR_MEMORY_ADVISOR(
  'IVF_FLAT',
  5000000,
  768,
  'FLOAT32',
  'SAMPLE_PER_NLIST=1024,DISTANCE=L2'
);

输出建议信息如下:
Suggested minimum vector memory is 579.2 MB, memory consumption when providing search service is 576.0 KB

9.4 分区表模拟


-- 16 分区均匀分布,假设最胖分区约 750000行

SELECT DBMS_VECTOR.INDEX_VECTOR_MEMORY_ADVISOR(
  'HNSW',
  5000000,
  768,
  'FLOAT32',
  'DISTANCE=L2,M=16,EF_CONSTRUCTION=200',
  750000
);

输出建议信息如下:
Suggested minimum vector memory is 21.3 GB

9.5 调整向量内存相关参数

-- 查看当前配置
SHOW PARAMETERS LIKE 'ob_vector_memory_limit_percentage';

-- 设置为 30%
ALTER SYSTEM SET ob_vector_memory_limit_percentage = 30;

-- 扩大至 59%:先降低 MemStore 占比
ALTER SYSTEM SET _memstore_limit_percentage = 25;
ALTER SYSTEM SET ob_vector_memory_limit_percentage = 59;

本文档基于 OceanBase V4.3.5 版本个人学习总结,上述内容个别地方可能理解有偏差或者总结不到位的,若阅读此文章有困惑的请以官方最新文档为准。

精选推荐