---
title: "创建向量索引 - OceanBase 数据库 V4.4.0 | OceanBase 文档中心"
description: 创建向量索引 本文介绍了 OceanBase 如何创建、搜索、维护和删除向量索引。 索引类型 OceanBase 支持的向量索引类型及其具体说明如下： 索引类型 描述 适用场景 HNSW 索引列最大维度为 4096。HNSW 索引是内存索引，需要完整载入内存。 HNSW_SQ HNSW_SQ 索引提供了和 HNSW …
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

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

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

# 创建向量索引

更新时间：2026-08-18 16:46:30

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.4.0/zh-CN/640.ob-vector-search/200.ob-vector-index.md)  

本文介绍了 OceanBase 如何创建、搜索、维护和删除向量索引。

## 索引类型

OceanBase 支持的向量索引类型及其具体说明如下：

| 索引类型 | 描述 | 适用场景 |
| --- | --- | --- |
| HNSW | 索引列最大维度为 4096。HNSW 索引是内存索引，需要完整载入内存。 | |
| HNSW_SQ | HNSW_SQ 索引提供了和 HNSW 索引相近的构建速度，搜索性能，召回率，但总的内存使用降低到原本的 1/2～1/3。 | 对性能和召回率有较高要求的场景。 |
| HNSW_BQ | HNSW_BQ 索引的召回率略低于 HNSW 索引，但显著减少了内存占用。BQ 量化压缩算法（Rabitq）能将向量压缩至原大小的 1/32，随着向量维度增加，HNSW_BQ 索引的内存优化效果更明显。 | |
| IVF（实验特性） | 基于数据库表实现的 IVF 索引，可不占用常驻内存。 | 对性能要求不高，但数据量较大，成本敏感的场景。 |
| IVF_PQ（实验特性） | 基于数据库表实现的 IVF_PQ 索引，可不占用常驻内存。在 IVF 基础上应用了 PQ 量化技术，索引的召回率略低于 IVF 索引，性能高于 IVF 索引，同时 PQ 量化压缩算法普遍场景下能将向量压缩至原大小的 1/16 ~ 1/32。 | 对性能要求不高，但数据量较大，成本敏感的场景。 |

一些其他说明：

- 稠密向量索引支持 L2、内积（IP）、余弦距离作为索引距离算法。
 - 支持带有过滤条件的向量查询。过滤条件可以是标量类型的条件，可以是空间关系，如 ST_Intersects 等。暂不支持多值索引/全文索引/全局索引作为预过滤器。
 - 支持同表创建向量索引和全文索引。
 - 向量索引对 Offline DDL 的支持情况请见[Offline DDL](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003382308)。
 - 向量索引搜索支持调用部分距离函数，具体请参见 [使用 SQL 函数](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003378339)。

## 准备工作

使用 HNSW/HNSW_SQ/HNSW_BQ 向量索引前，需要通过设置 [ob_vector_memory_limit_percentage](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003381620) 开启向量功能。IVF 索引不需要常驻内存，所以无需手动设置此参数来开启向量功能。

```sql
ALTER SYSTEM SET ob_vector_memory_limit_percentage = 30;

```

## 创建语法及说明

OceanBase 向量索引的创建支持**在建表时创建**和**后建**两种方式。创建时需要注意：

- 向量索引创建后，不支持任何参数的修改。
 - 创建向量索引必须带有 `VECTOR` 关键字。
 - 后建索引的参数和说明与建表时创建索引一致。
 - 如果数据量较大，建议先写完数据，再创建索引，以获得最佳搜索性能。
 - HNSW_SQ/IVF/IVF_PQ 索引均建议在写入数据后再创建索引，并在写入较多增量数据后进行索引重建。每个索引具体的创建说明见下文具体示例。

    HNSW/HNSW_SQ/HNSW_BQ   IVF/IVF_PQ

建表时创建索引语法：

```sql
CREATE TABLE table_name (
    column_name1 data_type1,
    column_name2 data_type2,
    ...,
    VECTOR INDEX index_name (column_name) WITH (param1=value1, param2=value2, ...)
);

```

后建索引语法：

```sql
-- 后建索引支持设置并行度，以提升索引构建性能，并行度最大设置不超过 CPU 核数 * 2
CREATE [/*+ paralell $value*/] VECTOR INDEX index_name ON table_name(column_name) WITH (param1=value1, param2=value2, ...);

```

`param` 参数说明：

| 参数 | 默认值 | 取值范围 | 是否必填 | 说明 | 备注 |
| --- | --- | --- | --- | --- | --- |
| distance |  | l2/inner_product/cosine | 是 | 指定向量距离算法类型。 | l2 表示欧氏距离，inner_product 表示内积距离，cosine 表示余弦距离。 |
| type |  | 目前支持 `hnsw` / `hnsw_sq`/ `hnsw_bq`。 | 是 | 指定索引类型。 | |
| lib | vsag | vsag | 否 | 指定向量索引库类型。 | 目前仅支持 VSAG 向量库。 |
| m | 16 | [5,128] | 否 | 每个节点的最大邻居数。 | 值越大，索引构建越慢，搜索性能越好。 |
| ef_construction | 200 | [5,1000] | 否 | 构建索引时的候选集大小。 | 值越大，索引构建越慢，索引质量越好。`ef_construction` 必须大于 `m`。 |
| ef_search | 64 | [1,1000] | 否 | 搜索时的候选集大小。 | 值越大，搜索越慢，召回率越高。 |
| extra_info_max_size | 0 | [0,16384] | 否 | 设置每个主键信息的最大大小（单位：字节）。将表的主键存储在索引中，以加快搜索速度。 | `0`：不存储主键信息。   `1`：强制存储主键信息，忽略大小限制。此时表的主键类型（详见下文）必须为支持的类型。   `大于 1`：设置主键信息的最大大小（单位：字节）。此时，需要满足以下条件：   - 主键信息的大小（计算方法见下文）必须小于设置的大小限制。 - 表的主键类型必须是支持的类型。 |

`extra_info_max_size` 支持的主键类型包括：

- [数值类型](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003383169)：支持其中的整数类型、浮点类型和 Bit_value 类型。
 - [日期时间类型](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003384050)
 - [字符类型](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003383171)：支持其中的 VARCHAR 类型。

主键信息的大小计算方法：

```sql
SET @table_name = 'test'; -- 替换为要查询的 table_name

SELECT
    CASE
        WHEN COUNT(*) <> COUNT(result_value) THEN 'not support'
        ELSE COALESCE(SUM(result_value), 'not support')
    END AS extra_info_size
FROM (
    SELECT
        CASE
            WHEN vdt.data_type_class IN (1, 2, 3, 4, 6, 8, 9, 14, 27, 28) THEN 8 -- 为数值类型 extra_info_size += 8
            WHEN oc.data_type = 22 THEN oc.data_length -- 为 varchar 类型 extra_info_size += data_length
            ELSE NULL -- 其他类型不支持
        END AS result_value
    FROM
        oceanbase.__all_column oc
    JOIN
        oceanbase.__all_virtual_data_type vdt
    ON
        oc.data_type = vdt.data_type
    WHERE
        oc.rowkey_position != 0
        AND oc.table_id = (SELECT table_id FROM oceanbase.__all_table WHERE table_name = @table_name)
) AS result_table;

-- 计算结果为 8 byte

```

```

后建索引语法：

```

| 参数 | 默认值 | 取值范围 | 是否必填 | 说明 | 备注 |
| --- | --- | --- | --- | --- | --- |
| distance |  | l2/inner_product/cosine | 是 | 指定向量距离算法类型。 | l2 表示欧氏距离，inner_product 表示内积距离，cosine 表示余弦距离。 |
| type |  | ivf_flat/ivf_pq | 是 | 指定 IVF 索引类型。 | |
| lib | ob | ob | 否 | 指定向量索引库类型。 | |
| nlist | 128 | [1,65536] | 否 | 聚类中心的个数。 | |
| sample_per_nlist | 256 | [1,int64_max] | 是 | 每个聚类中心的取样的数据量，后建索引中使用。 | |

## 搜索语法及说明

向量索引搜索是一种近似最近邻搜索，并不保证 100% 的结果正确。相应的向量搜索准确率的指标是召回率，例如在查 10 个最近邻时，如果可以稳定返回 9 个正确的结果，那么召回率就是 90%。召回率说明如下：

- 召回率受构建参数和搜索参数的影响。
 - 索引搜索参数在建索引时指定，之后不可修改。但可通过 session 变量设置：HNSW/HNSW_SQ 索引通过 `ob_hnsw_ef_search` 设置，IVF 索引通过 `ob_ivf_nprobes` 设置。如果设置了 session 变量，会优先使用它的值。具体设置方式请参见 [ob_hnsw_ef_search](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003381493) 和 [ob_ivf_nprobes](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003381480)。

稠密向量索引搜索语法具体如下：

```sql
SELECT ... FROM $table_name ORDER BY $distance_function($column_name, $vector_expr) [APPROXIMATE|APPROX] LIMIT $num (OFFSET $num);

```

搜索使用说明如下：

- 搜索语法要求：

     - 必须指定 `APPROXIMATE`/`APPROX` 关键字才会使用向量索引。
     - 必须包含 `ORDER BY` 和 `LIMIT` 子句。
     - `ORDER BY` 只支持单个向量条件。
     - `LIMIT + OFFSET` 的取值范围为 `(0, 16384]`。
 - 距离函数使用规则：

     - 指定 `APPROXIMATE`/`APPROX`，调用当前版本支持的距离函数，且与向量索引算法匹配，搜索会使用向量索引。
     - 指定 `APPROXIMATE`/`APPROX`，距离函数与向量索引算法不匹配，搜索不会使用向量索引，但也不会报错。
     - 指定 `APPROXIMATE`/`APPROX`，如果距离函数为当前版本不支持的距离函数，搜索不会使用向量索引，且会报错。
     - 未指定 `APPROXIMATE`/`APPROX`，调用当前版本支持的距离函数，搜索不会使用向量索引，但也不会报错。
 - 其他说明：

     - `WHERE` 条件会作为向量索引搜索后的过滤条件。
     - 不指定 `LIMIT` 子句会报错。

## 索引创建、搜索及删除示例

### 建表时创建索引

#### 稠密向量索引示例

##### HNSW 索引示例

#### 注意

创建 HNSW 索引时，索引名长度暂不支持超过 25 个字符，否则可能因为索引辅助表名长度超过 `index_name` 限制导致异常。未来版本会支持更长的索引名。

创建测试表。

```sql
CREATE TABLE t1(c1 INT, c0 INT, c2 VECTOR(10), c3 VECTOR(10), PRIMARY KEY(c1), VECTOR INDEX idx1(c2) WITH (distance=l2, type=hnsw, lib=vsag),  VECTOR INDEX idx2(c3) WITH (distance=l2, type=hnsw, lib=vsag));

```

写入测试数据。

```sql
INSERT INTO t1 VALUES(1, 1,'[0.203846,0.205289,0.880265,0.824340,0.615737,0.496899,0.983632,0.865571,0.248373,0.542833]', '[0.203846,0.205289,0.880265,0.824340,0.615737,0.496899,0.983632,0.865571,0.248373,0.542833]');

INSERT INTO t1 VALUES(2, 2, '[0.735541,0.670776,0.903237,0.447223,0.232028,0.659316,0.765661,0.226980,0.579658,0.933939]', '[0.213846,0.205289,0.880265,0.824340,0.615737,0.496899,0.983632,0.865571,0.248373,0.542833]');

INSERT INTO t1 VALUES(3, 3, '[0.327936,0.048756,0.084670,0.389642,0.970982,0.370915,0.181664,0.940780,0.013905,0.628127]', '[0.223846,0.205289,0.880265,0.824340,0.615737,0.496899,0.983632,0.865571,0.248373,0.542833]');

```

使用近似最近邻搜索。

```sql
SELECT * FROM t1 ORDER BY l2_distance(c2, [0.712338,0.603321,0.133444,0.428146,0.876387,0.763293,0.408760,0.765300,0.560072,0.900498]) APPROXIMATE LIMIT 1;

```

返回结果如下：

```shell
+----+------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
| c1 | c0   | c2                                                                                        | c3                                                                                         |
+----+------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
|  3 |    3 | [0.327936,0.048756,0.08467,0.389642,0.970982,0.370915,0.181664,0.94078,0.013905,0.628127] | [0.223846,0.205289,0.880265,0.82434,0.615737,0.496899,0.983632,0.865571,0.248373,0.542833] |
+----+------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
1 row in set

```

##### HNSW_SQ 索引示例

```sql
CREATE TABLE t2 (c1 INT AUTO_INCREMENT, c2 VECTOR(3), PRIMARY KEY(c1), VECTOR INDEX idx1(c2) WITH (distance=l2, type=hnsw_sq, lib=vsag));

```

##### HNSW_BQ 索引示例

```sql
CREATE TABLE t3 (c1 INT AUTO_INCREMENT, c2 VECTOR(3), PRIMARY KEY(c1), VECTOR INDEX idx3(c2) WITH (distance=l2, type=hnsw_bq, lib=vsag));

```

HNSW_BQ 索引 `distance` 参数仅支持 l2。

##### IVF 索引示例

#### 注意

创建 IVF 索引时，索引名长度暂不支持超过 33 个字符，否则可能因为索引辅助表名长度超过 `index_name` 限制导致异常。未来版本会支持更长的索引名。

```sql
CREATE TABLE ivf_vecindex_suite_table_test (c1 INT, c2 VECTOR(3), PRIMARY KEY(c1), VECTOR INDEX idx2(c2) WITH (distance=l2, type=ivf_flat));

```

### 后建索引

#### 注意

目前仅支持后建稠密向量索引。

#### HNSW 索引示例

创建测试表。

```sql
CREATE TABLE vec_table_hnsw (id INT, c2 VECTOR(10));

```

创建 HNSW 索引。

```sql
CREATE VECTOR INDEX vec_idx1 ON vec_table_hnsw(c2) WITH (distance=l2, type=hnsw);

```

查看创建的表。

```sql
SHOW CREATE TABLE vec_table_hnsw;

```

返回结果如下：

```shell
+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table     | Create Table                                                                                                                                                                                                                                                                                                                                                                                         |
+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| vec_table_hnsw | CREATE TABLE `vec_table_hnsw` (
  `id` int(11) DEFAULT NULL,
  `c2` VECTOR(10) DEFAULT NULL,
  VECTOR KEY `vec_idx1` (`c2`) WITH (DISTANCE=L2, TYPE=HNSW, LIB=VSAG, M=16, EF_CONSTRUCTION=200, EF_SEARCH=64) BLOCK_SIZE 16384
) DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 2 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 |
+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set

OceanBase(root@oceanbase)>SHOW INDEX FROM vec_table_hnsw;
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+------------+
| Table     | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment   | Index_comment | Visible | Expression |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+------------+
| vec_table |          1 | vec_idx1 |            1 | c2          | A         |        NULL | NULL     | NULL   | YES  | VECTOR     | available |               | YES     | NULL       |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+------------+
1 row in set

```

#### HNSW_SQ 索引示例

创建测试表。

```sql
CREATE TABLE vec_table_hnsw_sq (c1 INT AUTO_INCREMENT, c2 VECTOR(3), PRIMARY KEY(c1));

```

创建 HNSW_SQ 索引。

```sql
CREATE VECTOR INDEX vec_idx2 ON vec_table_hnsw_sq(c2) WITH (distance=l2, type=hnsw_sq, lib=vsag, m=16, ef_construction = 200);

```

##### HNSW_BQ 索引示例

```sql
CREATE VECTOR INDEX vec_idx3 ON vec_table_hnsw_bq(c2) WITH (distance=l2, type=hnsw_bq, lib=vsag, m=16, ef_construction = 200);

```

#### IVF 索引示例

创建测试表。

```sql
CREATE TABLE vec_table_ivf (c1 INT, c2 VECTOR(3), PRIMARY KEY(c1));

```

创建 IVF 索引。

```sql
CREATE VECTOR INDEX vec_idx3 ON vec_table_ivf(c2) WITH (distance=l2, type=ivf_flat);

```

### 删除索引

删除向量索引的语法具体如下：

```sql
DROP INDEX vec_idx1 ON vec_table;

```

查看删除的索引。

```sql
SHOW INDEX FROM vec_table;

```

返回结果如下：

```shell
Empty set

```

## 维护

增量数据过多的情况下，搜索性能会下降。为减小增量数据表的数据量，OceanBase 引入了 `DBMS_VECTOR` 对向量索引进行维护。

### 全量刷新（重建）

如果建立索引后更新或删除数据较多，建议使用 `REBUILD_INDEX` 过程进行全量刷新。说明和示例请参见 [REBUILD_INDEX](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003945225)。

默认情况下，全量刷新每 24 小时检查一次；若新增数据超过原有数据的 20%，则自动执行全量刷新。全量刷新会在后台异步执行，首先创建新的索引，然后替换旧索引。在重建过程中，旧索引保持可用状态，但整体过程相对较慢。

注意事项如下：

- 执行 [离线 DDL](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003382308) 操作（例如 `ALTER TABLE` 修改表结构或主键）时，将导致索引表的重建。由于重建索引无法指定并行度，系统会默认使用单线程，因此在数据量较大时，重建过程会比较缓慢，从而影响整个 离线 DDL 的执行效率。
 - 重建索引时如果需要修改索引参数，必须在参数列表中同时指定 `type` 和 `distance`，且 `type` 和 `distance` 必须和原索引类型一致，例如原来索引类型是 `hnsw`，距离算法是 `l2`，则重建时必须同时指定 `type=hnsw` 和 `distance=l2`。
 - 重建索引时支持：
     - 修改 `m`，`ef_search`，`ef_construction` 值。
     - 在线重建 `ef_search` 参数。
     - `hnsw` <-> `hnsw_sq` 的索引类型重建。
     - `ivf_flat` <-> `ivf_flat`，`ivf_pq` <-> `ivf_pq` 的索引类型重建。
     - 支持重建时设置并行度。示例见 [REBUILD_INDEX](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003945225)。
 - 重建索引时不支持：
     - 修改 `type` 和 `distance` 类型。
     - `hnsw` <-> `ivf` 的索引重建。
     - `hnsw` <-> `hnsw_bq` 的索引重建。
     - `ivf_flat`，`ivf_pq` 之间的交叉重建。

#### 配置重建参数

如果遇到合并窗口过多或者业务高峰期，可能会因为资源调度冲突导致重建失败，这时可以通过 `DBMS_VECTOR.SET_ATTRIBUTE` PL 系统包为索引配置重建的触发周期，避开合并窗口或业务高峰。

通过 `SET_ATTRIBUTE` 可为单个向量索引设置自动重建的并行度、触发阈值与触发周期：

```sql
-- 设置 rebuild 并行度
CALL DBMS_VECTOR.SET_ATTRIBUTE('idx1', 't1', 'parallel', '20');

-- 设置 rebuild 触发阈值（增量数据达到基线 50% 时触发）
CALL DBMS_VECTOR.SET_ATTRIBUTE('idx1', 't1', 'rebuild_trigger_percentage', '0.5');

-- 设置 rebuild 触发周期：每 600 秒检查一次
CALL DBMS_VECTOR.SET_ATTRIBUTE('idx1', 't1', 'rebuild_repeat_interval', 'FREQ=SECONDLY; INTERVAL=600');

-- 设置 rebuild 触发周期：每天 19:45:00 检查
CALL DBMS_VECTOR.SET_ATTRIBUTE('idx1', 't1', 'rebuild_repeat_interval', 'FREQ=DAILY; byhour=19;byminute=45;bysecond=0');

```

使用时的注意事项如下：

- 不同索引的 `rebuild_repeat_interval` 应错开，避免同一时段集中重建。

参数说明、约束和示例请参见 [SET_ATTRIBUTE](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000006840933)。

## 相关文档

- [使用 SQL 函数](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003378339)

 上一篇 下一篇 ![有帮助](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) 咨询热线
