---
title: "HNSW 系列索引 - OceanBase 数据库 V4.5.0 | OceanBase 文档中心"
description: HNSW 系列索引 本文档介绍了 OceanBase 数据库的稠密索引 HNSW 系列索引的创建、搜索、删除语法说明及示例。 索引语法及说明 创建 HNSW 系列索引包含 HNSW、HNSW_SQ 和 HNSW_BQ 三种索引，其创建支持 在建表时创建 和 后建 两种方式。创建时需要注意： 创建向量索引必须带有 VE…
---
切换语言

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

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

# HNSW 系列索引

更新时间：2026-02-10 17:56:10

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

本文档介绍了 OceanBase 数据库的稠密索引 HNSW 系列索引的创建、搜索、删除语法说明及示例。

## 索引语法及说明

### 创建

HNSW 系列索引包含 HNSW、HNSW_SQ 和 HNSW_BQ 三种索引，其创建支持**在建表时创建**和**后建**两种方式。创建时需要注意：

- 创建向量索引必须带有 `VECTOR` 关键字。
 - 后建索引的参数和说明与建表时创建索引一致。
 - 如果数据量较大，建议先写完数据，再创建索引，以获得最佳搜索性能。
 - HNSW_SQ 索引建议在写入数据后再创建索引，并在写入较多增量数据后进行索引重建。每个索引具体的创建说明见下文具体示例。
 - 创建 HNSW 索引时，索引名长度暂不支持超过 25 个字符，否则可能因为索引辅助表名长度超过 `index_name` 限制导致异常。未来版本会支持更长的索引名。
 - 建议在堆表上创建 HNSW 系列索引，以获得最佳搜索性能。

    建表时创建   后建索引

语法如下：

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

```

语法如下：

```sql
-- 后建索引支持设置并行度，以提升索引构建性能，并行度最大设置不超过 CPU 核数 * 2
CREATE [/*+ paralell $value*/] VECTOR INDEX index_name ON table_name(column_name2) 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`：设置主键信息的最大大小（单位：字节）。此时，需要满足以下条件：   - 主键信息的大小（计算方法见下文）必须小于设置的大小限制。 - 表的主键类型必须是支持的类型。 - 不是无主键表。 |
| refine_k | 4.0 | [1.0,1000.0] | 否 | #### 注意    该参数仅在创建 HNSW_BQ 索引时可指定。  该参数为浮点数类型，用于调整量化向量索引的重排比例。 | 该参数可以在创建索引时设置，也可以在搜索时指定：   - 如果搜索时没有设置，则使用创建索引时的值； - 如果搜索时设置了，则使用搜索时设置的值。 |
| refine_type | sq8   #### 注意    如果数据库是从旧版本升级到 V4.5.0 版本，则该参数默认值为 fp32。 | sq8/fp32 | 否 | #### 注意    该参数仅在创建 HNSW_BQ 索引时可指定。  用于设置量化向量索引的构建精度。 | 该值通过降低索引构建时的内存开销和索引构建时间来提高效率，但可能会影响召回率。 |
| bq_bits_query | 32 | 0/4/32 | 否 | #### 注意    该参数仅在创建 HNSW_BQ 索引时可指定。  用于设置量化向量索引的搜索精度，单位为 bit。 | 该值通过降低索引构建时的内存开销和索引构建时间来提高效率，但可能会影响召回率。 |
| bq_use_fht | true   #### 注意    如果数据库是从 V4.3.5 BP2 版本升级到 V4.5.0 版本，则该参数默认值为 false。 | true/false | 否 | #### 注意    该参数仅在创建 HNSW_BQ 索引时可指定。  用于设置是否使用 FHT 进行搜索。FHT（Fast Hadamard Transform）是一种用于加速向量内积计算的算法。 | |

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

- [数值类型](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004480572)：支持其中的整数类型、浮点类型和 Bit_value 类型。
 - [日期时间类型](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004481475)
 - [字符类型](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004480574)：支持其中的 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

```

### 搜索

HNSW 系列索引的搜索是一种近似最近邻（ANN）搜索，不保证 100% 的结果准确性。衡量其准确率的指标是召回率，例如在查询 10 个最近邻时，若能稳定返回 9 个正确结果，则召回率为 90%。

```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]`。
 - 不指定 `LIMIT` 子句会报错。

**距离函数使用规则：**

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

**其他说明：**

- `WHERE` 条件会作为向量索引搜索的过滤条件。
 - 召回率受构建参数和搜索参数的影响。
 - 索引搜索参数可以在创建索引时进行设置。如果在索引创建完成后需要调整，可以通过 [DBMS_VECTOR.REBUILD_INDEX](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004479887) 修改表级属性，也可以在查询时通过指定查询级别参数 `ef_search` 进行调整。

### 删除

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

```sql
DROP INDEX index_name ON table_name;

```

## 创建、搜索和删除示例

### 建表时创建

#### HNSW 示例

创建测试表。

```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` 和 `cosine`。

### 后建

```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

```

查看创建的索引。

```sql
SHOW INDEX FROM vec_table_hnsw;

```

返回结果如下：

```shell
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+-----------+---------------+---------+------------+
| 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);

```

HNSW_BQ 索引 `distance` 参数支持 `l2` 和 `cosine`。

### 删除

```sql
DROP INDEX vec_idx1 ON vec_table;

```

查看删除的索引。

```sql
SHOW INDEX FROM vec_table;

```

返回结果如下：

```shell
Empty set

```

## 相关文档

- 关于 HNSW 系列索引的内存估算与实际占用查询，请参见[索引内存管理](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004827711)
 - 关于 HNSW 系列索引的监控与维护，请参见[索引监控与维护](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004827716)

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