---
title: "索引类型选择 - OceanBase 数据库 V4.6.0 | OceanBase 文档中心"
description: 索引类型选择 OceanBase 数据库提供了多种不同算法的向量索引，用户可以依据使用场景选择合适的索引类型。 HNSW 还是 IVF？ OceanBase 的稠密索引分为两大类： 基于图的 HNSW 系列索引：HNSW、HNSW_SQ、HNSW_BQ。 基于磁盘的 IVF 系列索引：IVF、IVF_PQ。 这两种索…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.6.0

# 索引类型选择

更新时间：2026-06-23 17:45:39

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.6.0/zh-CN/640.ob-vector-search/200.ob-vector-index/300.ob-dense-vector-index/150.ob-dense-index-best-practice.md)  

OceanBase 数据库提供了多种不同算法的向量索引，用户可以依据使用场景选择合适的索引类型。

## HNSW 还是 IVF？

OceanBase 的稠密索引分为两大类：

- 基于图的 HNSW 系列索引：HNSW、HNSW_SQ、HNSW_BQ。
 - 基于磁盘的 IVF 系列索引：IVF、IVF_PQ。

这两种索引类型各有侧重。HNSW 系列索引通常提供更高的查询性能，但需要占用更多常驻内存；而 IVF 系列索引在缓存充足时性能表现良好，且能够不依赖常驻内存运行。然而，选择 HNSW 还是 IVF 并非仅基于内存考量，业务场景、数据规模、性能指标以及资源约束等多个维度都需综合评估，下文将详细对比其核心差异并提供选择建议。

### 核心差异对比

| 对比维度 | HNSW 系列 | IVF 系列 |
| --- | --- | --- |
| 存储方式 | 基于内存的图结构索引 | 基于磁盘的索引 |
| 内存占用 | 需要完整载入内存，内存占用高 | 可不占用常驻内存，内存占用低 |
| 查询性能（QPS） | 极高，毫秒级响应 | 较高，在缓存充足时接近 HNSW |
| 召回率 | 高，可达 99% | 较高，略低于 HNSW，可通过参数调优 |
| 构建速度 | 较慢，需要构建图结构 | 较快，基于聚类算法 |
| 适用数据量 | 百万级到亿级 | 百万级到十亿级 |
| 成本 | 内存成本高 | 存储成本低，适合大规模数据 |
| 实时性 | 支持实时 DML 操作 | 支持实时 DML 操作 |

### 决策流程图

#### 说明

- 在选择索引类型前，您需要先参考[向量索引内存管理](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005682091)估算内存用量。
 - 决策流程图中的选择建议均以 1024 维向量为参考，若实际维度不同，可按比例近似换算所需资源。
 - 决策流程图主要从内存成本角度出发，帮助您决策索引类型。
 - 即使租户内存充足，也不一定总是选择 HNSW 等最高规格索引。如果对极致性能有较高需求，可以考虑 HNSW_SQ 等更具性价比的选项。

![决策流程图](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/observer/V4.4.1/%E5%90%91%E9%87%8F/%E7%B4%A2%E5%BC%95%E5%86%B3%E7%AD%96%E6%B5%81%E7%A8%8B%E5%9B%BE_251212.png)

#### 注意

这里仅列举了部分常用场景的决策流程，如果通过上述路径无法判断，或有其他需求，请联系 OceanBase 技术支持。

## 是否使用分区表？

使用分区表的主要目的是为了解决大数据量的场景，其次是如果查询条件可以用于做分区键，那么通过分区裁剪可以提升查询性能。在以下两种场景下建议使用分区表：

- 数据量达到几千万或亿级以上：当数据量非常大时，使用分区表可以将数据分散到多个分区，每个分区独立构建索引，从而降低单次查询负载，提升整体查询性能。
 - 查询条件中有明确的标量列可以用作分区裁剪：例如，如果 `label` 字段总是会出现在 `WHERE` 条件中，那么就可以考虑以 `label` 作为分区键创建分区表，通过分区裁剪减少需要查询的分区数量。

具体使用建议如下：

### 分区划分

在使用向量索引时，分区数量不宜过多。与标量索引不同，向量索引（如 HNSW）在相同配置下，索引规模从 100 万向量增大到 200 万向量，查询 TopK 所需的计算开销并不会显著增加。因此，如果不能利用分区裁剪，过多的分区反而可能降低性能。另外，单个分区过大不仅会导致索引重建耗时增加，还会影响与标量条件联合查询时的效率。

综上，**推荐将每个分区内的数据量控制在 2000 万以下，并优先选择能够支持分区裁剪的字段作为分区键**。

### 算法选择

在大数据量下建议选择 HNSW_BQ 或 IVF_PQ 索引。如需使用其他索引，请参考下文[内存占用](#内存占用)章节进行估算。

### 内存占用

#### HNSW_BQ

对于 HNSW_BQ 索引，建议 `租户内存 > HNSW_BQ 查询时总内存占用 + 单分区 HNSW_SQ 索引占用`。内存预估流程如下：

1. 优先通过 `INDEX_VECTOR_MEMORY_ADVISOR` 函数计算 HNSW_BQ 及 HNSW_SQ 索引在构建及查询过程中的推荐内存值。
 2. 基于上述工具获得的推荐内存值，计算并确定租户所需内存总量。

例如，假设拥有 1 亿条 1024 维向量数据，采用 10 个分区（每个分区约 1000 万向量）。按照上述流程，具体计算过程如下：

```sql
-- 指定 REFINE_TYPE=SQ8 即可直接准确获取 HNSW_BQ 索引在构建及查询过程中的推荐内存值，
-- 无需再额外单独计算 HNSW_SQ 索引的占用。这是因为 HNSW_BQ 在构建时默认使用 SQ8 量化算法构图，
-- 指定 refine_type=sq8 后，函数会自动将该索引构建时所需的 SQ8 量化向量所需的内存计算在内
-- HNSW_BQ 索引的推荐内存值为 74.6 GB，查询时内存占用为 57.4 GB，我们取用推荐内存值
SELECT DBMS_VECTOR.INDEX_VECTOR_MEMORY_ADVISOR('HNSW_BQ',100000000,1024,'FLOAT32','M=32,DISTANCE=COSINE,REFINE_TYPE=SQ8', 10000000);
+------------------------------------------------------------------------------------------------------------------------------+
| DBMS_VECTOR.INDEX_VECTOR_MEMORY_ADVISOR('HNSW_BQ',100000000,1024,'FLOAT32','M=32,DISTANCE=COSINE,REFINE_TYPE=SQ8', 10000000) |
+------------------------------------------------------------------------------------------------------------------------------+
| Suggested minimum vector memory is 74.6 GB, memory consumption when providing search service is 57.4 GB                      |
+------------------------------------------------------------------------------------------------------------------------------+
1 row in set

-- 向量内存在租户内存中的占比默认为 50%，因此总租户内存为
SELECT 74.6/0.5;
+--------------------------------------------------------------------------------------------------------------+
| 74.6/0.5 = 149.2 GB |
+--------------------------------------------------------------------------------------------------------------+
1 row in set

-- 考虑到实际环境中新写入数据未及时压缩的情况，建议适当预留冗余
SELECT 149.2 * 1.2;
+--------------------------------------------------------------------------------------------------------------+
| 149.2 * 1.2 = 179.04 GB |
+--------------------------------------------------------------------------------------------------------------+
1 row in set

-- 因此，建议租户内存配置为 179 GB

```

#### IVF 系列

对于 IVF 和 IVF_PQ 索引，建议 `租户内存 > 单个分区构建内存 + 所有分区常驻内存总和`。例如，1 亿条数据，采用 10 个分区，每个分区约 1000 万向量，单分区构建时大约需要 2.7 GB 内存，查询时 10 个分区的 IVF_PQ 索引合计常驻约 1.1 GB（110 MB/分区）。因此，最低需配置大约 3 GB 内存。建议在此基础上适当留有富余，推荐配置 6 GB 内存。其他数据量场景可参照上述方法估算。

### 构建和查询参数

索引构建与查询参数建议以单分区的最大数据量为基准设置。详见下文[索引参数建议](#索引参数建议)章节。

### 性能和召回率

- 若查询条件可以裁剪到单个分区：则性能和召回率与单分区场景一致，详见下文不同规模数据量详细说明的章节。
 - 若无法裁剪到单分区：QPS 可按单 OBServer 节点上的分区数量等比例预估（例如，单节点包含 3 个分区，则 QPS 约为单分区性能的 1/3）；由于跨分区查询会合并更多候选结果，实际召回率通常高于单分区情形。

## 索引参数建议

### HNSW 系列

同系列的索引在不同的数据量下，推荐的索引构建和查询参数是不相同的。本节给出百万和千万数据量下，768 维度向量，HNSW/HNSW_SQ/HNSW_BQ 索引的建议配置供参考。对于亿级别的向量数据，请参考本文后续章节选用 IVF_PQ 索引，或分区表下的 HNSW_BQ 索引。

#### 注意

对于数据量预计会增长的场景，建议根据最终数据量进行参数设置。

#### 注意

HNSW_BQ 是高压缩率的量化算法，在低维向量下的召回率上限可能较低。为避免性能损失，建议 HNSW_BQ 使用在 512 维及以上的向量上。

| 场景 | 索引类型 | 参数建议 |
| --- | --- | --- |
| 最高召回   （内存占用最多） | HNSW | 百万数据量：m = 16，ef_construction = 200，ef_search = 100，其他参数默认 |
| 最高性能   （内存占用较少） | HNSW_SQ | 百万数据量：m = 16，ef_construction = 200，ef_search = 100，其他参数默认   千万数据量：m = 32，ef_construction = 400，ef_search = 350，其他参数默认 |
| 最佳性价比   （内存占用少，性能好） | HNSW_BQ | 百万数据量：m = 16，ef_construction = 200，ef_search = 100，其他参数默认   千万数据量：m = 32，ef_construction = 400，ef_search = 1000，refine_k = 10，其他参数默认   亿级数据量：使用分区表，m = 32，ef_construction = 400，ef_search = 1000，refine_k = 10，其他参数默认 |

#### 百万级数据量详细说明

以 100 万条 768 维向量数据为例（使用上表中的构建参数），补充说明内存占用和召回率调优：

内存占用：

| 索引类型 | 建议租户内存 | 说明 |
| --- | --- | --- |
| HNSW | 15 GB | 向量索引内存大小建议值为 7.3 GB。租户内存大于 8 GB 时，向量索引默认最多使用租户内存的 50%；租户内存小于等于 8 GB 时，向量索引默认最多使用租户内存的 40%。因此大约需要 15 GB 的租户内存。 |
| HNSW_SQ | 6 GB | 向量索引内存大小建议值为 2.1 GB。 |
| HNSW_BQ | 6 GB | HNSW_BQ 索引在构建时需要用到高精度的向量，所以构建过程中和 HNSW_SQ 的内存需求一样，都是 6 GB。HNSW_BQ 索引默认采用 SQ8 量化方法，索引构建完成后，内存占用会大幅降低，仅约 405 MB。   上述说明适用于非分区表场景。如果使用分区表，OceanBase 会根据租户分配的内存动态调节可以同时构建的分区数量。实际配置时，建议租户内存至少包括 HNSW_BQ 查询时的内存占用量，加上构建某个分区时 HNSW_SQ 需要的内存，留有一定冗余，具体计算方式请参考上文 **内存占用** 章节。 |

召回率调优：

通过调整 `ef_search` 和 `refine_k`（仅 HNSW_BQ）参数，可以通过更多的向量计算来提高召回率，但相应的会降低查询性能。在不同 TopN 下可将参数设置为下表中的建议值，如果需要进一步提升召回率，则可将参数值设置得更大一些。

#### 注意

召回率和数据特征有直接关系，下表给出的是 768 维标准数据集下，召回率达到 0.95 左右的建议值。

| TopN | ef_search | refine_k（仅 HNSW_BQ） |
| --- | --- | --- |
| Top10 | 64 | 4 |
| Top100 | 240 | 4 |

极限召回率说明：

几种索引算法的极限召回率不同。在本节设置建议的构建参数下，将 `ef_search` 设置为 1000 时，查询的召回率可能有所提升，但QPS 会降低到 0.95 召回率时的 1/3，同时调大ef_search，并不是所有类型的索引召回率都能无限提升，仅有 HNSW 能达到 0.99 以上的召回率。HNSW_BQ 索引可以通过进一步增加 `refine_k` 来提高召回率，但性能也会进一步下降。

极限召回率参考值（ef_search = 1000）：

- HNSW 索引：召回率 0.991
 - HNSW_SQ 索引：召回率 0.9786
 - HNSW_BQ 索引：召回率 0.9897（ef_search = 1000，refine_k = 10）

#### 千万级数据量详细说明

以 1000 万条 768 维向量数据为例（使用上表中的构建参数），补充说明内存占用和召回率调优：

内存占用：

| 索引类型 | 建议租户内存 | 说明 |
| --- | --- | --- |
| HNSW | 160 GB | 向量索引内存大小建议值为 76.3 GB。 |
| HNSW_SQ | 48 GB | 向量索引内存大小建议值为 22.6 GB。 |
| HNSW_BQ | 48 GB | HNSW_BQ 索引在构建过程中需要使用高精度的向量。HNSW_BQ 默认使用 HNSW_SQ 作为索引构建中的缓存，因此对于非分区表，HNSW_BQ 所需要的内存和 HNSW_SQ 相同。构建完成后，HNSW_BQ 索引只占用约 5.4 GB 的内存。 |

召回率调优：

| TopN | ef_search | refine_k（仅 HNSW_BQ） |
| --- | --- | --- |
| Top10 | 100 | 4 |
| Top100(HNSW/HNSW_SQ) | 350 | - |
| Top100(HNSW_BQ) | 1000 | 10 |

### IVF 系列

| 场景 | 索引类型 | 参数建议 |
| --- | --- | --- |
| 低维度   （384 维及以下） | IVF | 千万数据量：使用分区表，nlist=3000   亿级数据量：使用分区表，nlist=3000 |
| 低成本   （内存占用极少） | IVF_PQ | 百万数据量：nlist=1000, m=向量维度/2   千万数据量：nlist=3000, m=向量维度 / 2   亿级数据量：使用分区表，nlist=3000, m=向量维度 / 2 |

为了兼顾聚类中心数量与每个中心包含的数据量，通常推荐将 nlist 设置为数据量的平方根。例如，1000 万数据建议 nlist 选取 3000 左右。在使用 IVF_PQ 时，m 参数建议取向量维度（dim）的一半。

#### 注意

IVF_PQ 是高压缩率的量化算法，在低维向量下的召回率上限可能较低。为避免性能损失，建议 IVF_PQ 使用在 128 维及以上的向量上。

#### 千万级数据量（结合分区表）

以 1000 万条 768 维向量数据为例（使用上表中的构建参数），补充说明内存占用和召回率调优：

内存占用：

| 索引类型 | 索引参数 | 内存开销（构建开销/常驻开销） |
| --- | --- | --- |
| IVF | distance=l2, nlist=3000 | 2.7 GB/ 10.5 MB |
| IVF_PQ | distance=l2, nlist=3000, m=384 | 4.0 GB/ 1.3 GB |
| IVF_PQ | distance=cosine, nlist=3000, m=384 | 2.7 GB/ 11.4 MB |

表格中`构建开销`表示索引在创建过程中临时占用的内存，构建完成后这部分内存会被释放；`常驻开销`是指索引构建完成后，IVF 向量索引持续占用的内存。

对于 IVF_PQ 索引，如果选择 distance = l2，会因需要存储额外的预计算结果而占用更多常驻内存；相比之下，使用 distance = inner_product 或 cosine 时常驻内存消耗较低。因此，实际应用中通常推荐优先选择 inner_product 或 cosine 作为距离类型，以优化内存资源。

召回率调优：

通过调整 `nprobes` 参数，可以通过更多的向量计算来提高召回率，但相应的会降低查询性能。在不同 TopN 下可将参数设置为下表中的建议值，如果需要进一步提升召回率，则可将参数值设置得更大一些。

| TopN | nprobes |
| --- | --- |
| Top10 | 1 |
| Top100 | 20 |

#### 亿级数据量（结合分区表）

当向量数据量达到亿级及以上时，强烈推荐采用分区表结合 IVF 类索引。随着数据规模和 nlist 参数的增加，单个 IVF 索引的查询开销也会显著提升。通过将数据拆分到多个分区，每个分区分别构建较小规模的 IVF 索引，可有效降低单次查询负载，并通过分区并行查询进一步提升整体查询性能和召回率。

对于多分区表场景，由于 IVF 索引为本地索引，每个分区都会独立构建 IVF 索引，因此建议按照每个分区的平均数据量来计算 nlist 的取值。例如，1 亿条 768 维向量，分为 10 个分区时，每个分区约 1000 万条数据，nlist 推荐设为 sqrt(1000 万)=3162。

以 1 亿条 768 维向量数据为例（使用上表中的构建参数），补充说明内存占用和召回率调优：

内存占用：

对于多分区场景，由于 IVF 索引为本地索引，每个分区都会独立构建和维护一个 IVF 索引，因此常驻内存的总占用需按分区数量进行累加。例如，下表中单个 IVF 索引的常驻内存为 10.5 MB，若有 10 个分区，则总常驻内存约为 10.5 × 10 = 105 MB。

| 索引类型 | 索引参数 | 内存开销（构建开销/常驻开销） |
| --- | --- | --- |
| IVF | distance=l2, nlist=10000 | 2.7 GB/ 13.1 * 10 MB |
| IVF_PQ | distance=l2, nlist=10000, m=384 | 4.0 GB/ 1.6 * 10 GB |
| IVF_PQ | distance=cosine, nlist=10000, m=384 | 2.7 GB/ 14.2 * 10 MB |

召回率调优：

在分区表场景下，由于每个分区会独立执行 IVF 索引查询，用户在查询时如果涉及多个分区，会分别从每个分区检索 TopN 结果，然后将所有分区的结果进行汇总和重排序。这样不仅提升了整体的搜索准确率，还使得实际召回率通常高于单分区场景。因此，在多分区表中，可以适当降低 nprobes 参数的设置，即可获得与单分区表相当的召回率。

| TopN | nprobes |
| --- | --- |
| Top10 | 1 |
| Top100 | 10 |

## 相关文档

- 参数详细说明和调优请参见 [HNSW 索引](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005682591)和 [IVF 索引](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005682588)

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
