この記事では、OceanBaseデータベースのHNSWシリーズのインデックスの作成、検索、削除の構文と例を紹介します。
注意
HNSW_BQインデックスはV4.3.5 BP2バージョンからサポートされています。
インデックス構文と説明
作成
HNSW シリーズのインデックスには、HNSW、HNSW_SQ、および HNSW_BQ の 3 種類が含まれており、作成方法はテーブル作成時と後から作成するの 2 通りがサポートされています。作成時には以下の点に注意してください。
- ベクトルインデックスを作成する際は、
VECTORキーワードを必ず指定する必要があります。 - 後から作成するインデックスのパラメータと説明は、テーブル作成時にインデックスを作成する場合と同じです。
- データ量が大きい場合は、データの書き込みを完了してからインデックスを作成することで、最適な検索性能を得ることができます。
- HNSW_SQ インデックスは、データの書き込み後に作成することを推奨します。また、大量の増分データを書き込んだ後は、インデックスの再構築を行うことを推奨します。各インデックスの具体的な作成方法については、以下の例を参照してください。
- HNSW インデックスを作成する際、インデックス名の長さは 25 文字を超えると、インデックスのアシスタントテーブル名が
index_nameの制限を超える可能性があるため、例外が発生する場合があります。今後のバージョンでは、より長いインデックス名がサポートされます。
構文は以下のとおりです:
CREATE TABLE table_name (
column_name1 data_type1,
column_name2 VECTOR(dim), -- ベクトル列。VECTOR タイプを指定し、dimension はベクトルの次元を表します。
...,
VECTOR INDEX index_name (column_name2) WITH (param1=value1, param2=value2, ...)
);
構文は以下のとおりです:
-- 後からインデックスを作成する際は、並列度を設定することでインデックス構築の性能を向上させることができます。並列度の最大値は 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] | いいえ |
注意このパラメータは V4.3.5 BP3 以降のバージョンからサポートされています。HNSW_BQ インデックスを作成する場合にのみ指定できます。 |
このパラメータはインデックス作成時に設定することも、検索時に指定することもできます:
|
| refine_type | sq8
注意クラスタが旧バージョンから V4.3.5 BP3 にアップグレードされた場合、このパラメータのデフォルト値は fp32 になります。 |
sq8/fp32 | いいえ |
注意このパラメータは V4.3.5 BP3 以降のバージョンからサポートされています。HNSW_BQ インデックスを作成する場合にのみ指定できます。 |
この値は、インデックス構築時のメモリ消費とインデックス構築時間を削減することで効率を向上させますが、リコール率に影響を与える可能性があります。 |
| bq_bits_query | 32 | 0/4/32 | いいえ |
注意このパラメータは V4.3.5 BP3 以降のバージョンからサポートされています。HNSW_BQ インデックスを作成する場合にのみ指定できます。 |
この値は、インデックス構築時のメモリ消費とインデックス構築時間を削減することで効率を向上させますが、リコール率に影響を与える可能性があります。 |
| bq_use_fht | true
注意クラスタが旧バージョンから V4.3.5 BP3 にアップグレードされた場合、このパラメータのデフォルト値は false になります。 |
true/false | いいえ |
注意このパラメータは V4.3.5 BP3 以降のバージョンからサポートされています。HNSW_BQ インデックスを作成する場合にのみ指定できます。 |
extra_info_max_size でサポートされている主キーのタイプは以下のとおりです:
主キー情報のサイズの計算方法:
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バイトです
:::
検索
HNSW シリーズインデックスの検索は、近似最近傍 (ANN) 検索であり、100% の結果の正確性を保証しません。その正確性を測る指標は、リコール率です。例えば、10 件の最近傍をクエリする場合、9 件の正解を安定して返すことができれば、リコール率は 90% となります。
SELECT ... FROM table_name
ORDER BY distance_function(column_name, vector_expr) [APPROXIMATE|APPROX]
LIMIT num (OFFSET num)
[PARAMETERS (param1=value1, ...)];
検索構文の要件:
APPROXIMATE/APPROXキーワードを指定しないと、検索はベクトルインデックスではなく、フルテーブルスキャンを使用します。ORDER BYとLIMITクラウスを含める必要があります。ORDER BYは単一のベクトル条件のみをサポートします。LIMIT + OFFSETの範囲は(0, 16384]です。LIMITクラウスを指定しないとエラーが発生します。
距離関数の使用ルール:
APPROXIMATE/APPROXを指定した場合、現在のバージョンでサポートされている距離関数を呼び出し、その関数がベクトルインデックスアルゴリズムと互換性がある場合、検索はベクトルインデックスを使用します。APPROXIMATE/APPROXを指定した場合、距離関数がベクトルインデックスアルゴリズムと互換性がない場合、検索はベクトルインデックスを使用せず、エラーも発生しません。APPROXIMATE/APPROXを指定した場合、距離関数が現在のバージョンでサポートされていない場合、検索はベクトルインデックスを使用せず、エラーが発生します。APPROXIMATE/APPROXを指定しない場合、現在のバージョンでサポートされている距離関数を呼び出すと、検索はベクトルインデックスを使用せず、エラーも発生しません。
その他の注意事項:
WHERE条件は、ベクトルインデックス検索のフィルタリング条件となります。- リコール率は、構築パラメータと検索パラメータの影響を受けることがあります。
- インデックス検索パラメータは、インデックスを作成する際に指定し、その後は変更できません。ただし、セッション変数
ob_ivf_nprobesを使用して、検索時のクラスタ中心数を設定することができます。セッション変数が設定されている場合は、その値が優先されます。具体的な設定方法については、ob_ivf_nprobesを参照してください。
注意
V4.3.5 BP5以降のバージョンから、PARAMETERS(similarity=$value) クラウスを使用して、類似度しきい値を指定した検索がサポートされています。
- 類似度しきい値パラメータ (
similarity):- 構文:
LIMITクラウスの後にPARAMETERS (similarity=$value)を追加します。ここで、$valueは類似度しきい値であり、範囲は[0, 1]です。通常、類似度値が大きいほど、より類似しており、距離は小さくなります。ただし、inner_productの場合、距離が大きいほどより類似していることになります。 - 機能:類似度しきい値を指定すると、返される結果には、そのしきい値以上である結果のみが含まれます。
- サポートされる HNSW シリーズインデックスタイプ:HNSW、HNSW_SQ、HNSW_BQ
- サポートされる距離タイプ:
- クエリ時に、
cosine_distanceおよびl2_distanceの距離タイプのインデックスに対して類似度を指定できます。l2_distanceの場合、ベクトルに対して L2 正規化処理を行うことを推奨します。これにより、類似度検索の正確性が向上します。ベクトルの正規化に関する説明と例については、SQL関数の使用-ベクトルの正規化を参照してください。 - 距離タイプが
inner_productのインデックスに対して、クエリ時に類似度を指定することはサポートされていません(エラーnot supportが発生します)。
- クエリ時に、
- 類似度と距離の対応関係:
cosine_distance=2 - 2 * similarityl2_distance=sqrt(1 / similarity -1)
- 構文:
削除
ベクトルインデックスを削除する構文は次のとおりです:
DROP INDEX index_name ON table_name;
作成、検索、削除の例
テーブル作成時に作成する
HNSWの例
テストテーブルを作成します。
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));
テストデータを書き込みます。
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]');
近似最近傍検索を使用します。
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;
結果は次のとおりです。
+----+------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
| 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の例
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の例
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 をサポートしています。cosine は V4.3.5 BP4 からサポートされています。
後から作成する
HNSWの例
テストテーブルを作成します。
CREATE TABLE vec_table_hnsw (id INT, c2 VECTOR(10));
HNSW インデックスを作成します。
CREATE VECTOR INDEX vec_idx1 ON vec_table_hnsw(c2) WITH (distance=l2, type=hnsw);
作成されたテーブルを確認します。
SHOW CREATE TABLE vec_table_hnsw;
結果は次のとおりです。
+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 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
作成されたインデックスを確認します。
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の例
テストテーブルを作成します。
CREATE TABLE vec_table_hnsw_sq (c1 INT AUTO_INCREMENT, c2 VECTOR(3), PRIMARY KEY(c1));
HNSW_SQ インデックスを作成します。
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の例
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 をサポートしています。cosine は V4.3.5 BP4 からサポートされています。
削除
DROP INDEX vec_idx1 ON vec_table;
削除されたインデックスを確認します。
SHOW INDEX FROM vec_table;
結果は次のとおりです。
Empty set