# ベクトル検索
ベクトル検索は、データをベクトルとして表現する検索方法です。画像検索、ビデオ検索、テキスト検索などのアプリケーションや、画像分類やクラスタリングなどの機械学習アプリケーションでよく使用されます。
このセクションでは、ベクトル検索を高速化するためのベクトルインデックスの作成と操作方法、さらに異なるタイプのベクトルインデックスの設定方法について紹介します。
# コマンドリファレンス
# ベクトルを含むテーブルの作成
現在、私たちは2種類のベクトルをサポートしています:float32の配列とバイナリ文字列です。それに応じて、埋め込みベクトルはMyScale内でArray(Float32)またはFixedStringとして表されます。
WARNING
ベクトルのバイナリ文字列タイプは、DBバージョン1.3.1以降でのみ適用可能です。
TIP
埋め込みベクトル列のすべてのベクトルは、必ず同じ次元を持たなければなりません。
- float32の配列のベクトルの場合、エラーを避けるために
CONSTRAINTを使用します。例えば、CONSTRAINT constraint_name_1 CHECK length(data) = 128。 - バイナリ文字列のベクトルの場合、固定長
FixedString(N)タイプとして表します。その結果、これらのベクトルの次元制約を指定する必要はありません。なぜなら、各ベクトルの次元は一貫しており、8 * Nと等しくなければならないからです。
以下は、異なるタイプのベクトルデータのためのテーブルを作成する例です。
-- 128次元のfloat32ベクトルの配列と長さ制約のあるベクトル列を持つテーブルを作成する
CREATE TABLE test_vector
(
id UInt32,
data Array(Float32),
CONSTRAINT check_length CHECK length(data) = 128,
date Date,
label Enum8('person' = 1, 'building' = 2, 'animal' = 3)
) ENGINE = MergeTree ORDER BY id
-- 128次元(16バイト)のバイナリ文字列ベクトルを持つテーブルを作成する
CREATE TABLE test_binary_vector
(
id UInt32,
binary_data FixedString(16),
date Date,
label Enum8('person' = 1, 'building' = 2, 'animal' = 3)
) ENGINE = MergeTree ORDER BY id
注意
データ型の名前は大文字と小文字が区別され、大文字と小文字の区別が正しくない場合はエラーが返されます。
# ベクトルインデックスの作成
ベクトル検索を実行する前に、ベクトルインデックスを作成する必要があります。ベクトルインデックスを作成するための構文は以下の通りです:
ALTER TABLE [db.]table_name
ADD VECTOR INDEX index_name column_name
[TYPE index_type('param1 = value1', 'param2 = value2', ...)]
index_name: ベクトルインデックスの名前。column_name: ベクトルインデックスが作成される列の名前。この列は、Array(Float32)またはFixedStringのいずれかのタイプでなければなりません。Array(Float32)タイプの場合、配列の長さを指定する制約が必要です。index_type: ベクトルインデックスの特定のタイプ。
TIP
float32ベクトルの配列については、最適な結果を得るためにMSTGアルゴリズムの使用を強くお勧めします。ただし、以下の他のインデックスタイプも利用可能です。
FLAT: 比較のためのブルートフォースアルゴリズムScaNN: Google Research が開発したスケーラブル最近傍探索アルゴリズムIVFファミリー:IVFFLAT、IVFSQ、IVFPQを含むHNSWファミリー:HNSWFLAT、HNSWSQ、HNSWPQを含む
バイナリ文字列ベクトルのインデックスタイプとしては、BinaryMSTG、BinaryFLAT、BinaryIVF、BinaryHNSW が利用可能です。これらの中で、最適な結果を得るためにも、BinaryMSTG アルゴリズムの使用を強くお勧めします。
NOTE
MSTG と BinaryMSTG のベクトルインデックスタイプは、SaaS/BYOC バージョンでのみ提供されており、その他のタイプはすべてのバージョン(オープンソース、SaaS、BYOCを含む)で利用可能です。
index_type を指定せずにデフォルトのベクトルインデックスを作成する方法も2つあります:
index_typeがDEFAULTに等しいベクトルインデックスを作成します。- ベクトルインデックスを作成する際に
TYPE index_type(...)フィールドを指定する必要はありません。
TIP
オープンソース版では、デフォルトで ScaNN と BinaryIVF のベクトルインデックスを作成します。一方、SaaS/BYOC 版では、デフォルトで MSTG と BinaryMSTG のベクトルインデックスを作成します。
例えば、SaaS 上の test_float_vector テーブルの vector 列に対して MSTG タイプの idx という名前のベクトルインデックスを作成するには、次のいずれかのコマンドを使用します:
-- ベクターインデックスのタイプを指定します。
ALTER TABLE test_float_vector ADD VECTOR INDEX idx vector TYPE MSTG
-- index_type が DEFAULT に等しいベクトルインデックスを作成します。
ALTER TABLE test_float_vector ADD VECTOR INDEX idx vector TYPE DEFAULT
-- ベクターインデックスのタイプが指定されていません。
ALTER TABLE test_float_vector ADD VECTOR INDEX idx vector
TIP
特定のタイプのパラメータの詳細については、ベクトルインデックス構成オプションの説明セクションを参照してください。パフォーマンスチューニングのアドバイスについては、パフォーマンスチューニングのアドバイスセクションを参照してください。
DBバージョンv1.4.0以上では、MyScaleではテーブルに複数のベクトルインデックスを作成できます。ただし、ベクトル列には1つのベクトルインデックスしか許可されません。例えば、複数のベクトル列を持つテーブルを作成できます:
-- 異なる次元を持つ2つのfloat32ベクトル列を持つテーブルを作成
CREATE TABLE test_multiple_vectors
(
id UInt32,
vec1 Array(Float32),
vec2 Array(Float32),
CONSTRAINT check_length CHECK length(vec1) = 128,
CONSTRAINT check_length CHECK length(vec2) = 64,
date Date,
label Enum8('person' = 1, 'building' = 2, 'animal' = 3)
) ENGINE = MergeTree ORDER BY id
その後、各ベクトル列にベクトルインデックスを作成できます:
-- vec1列にMSTGインデックスタイプを追加
ALTER TABLE test_multiple_vectors ADD VECTOR INDEX idx1 vec1 TYPE MSTG
-- vec2列に別のMSTGベクトルインデックスを追加
ALTER TABLE test_multiple_vectors ADD VECTOR INDEX idx2 vec2 TYPE MSTG
# ベクトルインデックスの削除
ベクトルインデックスを削除するには、次の構文を使用します。これにより、インデックスが削除され、関連するメモリとディスクリソースが解放されます。インデックスが現在構築中である場合、構築プロセスも即座に停止されます。
ALTER TABLE [db.]table_name DROP VECTOR INDEX index_name
# ベクトルインデックスのステータスの確認
ベクトルインデックスの現在のステータスを確認するには、system.vector_indicesシステムテーブルを使用できます。次の構文を使用すると、すべての既存のベクトルインデックスを表示できます:
SELECT * FROM system.vector_indices
テーブル名やその他の条件で結果をフィルタリングするために、WHERE句を使用することもできます。たとえば、test_float_vectorなどの特定のテーブルのベクトルインデックスを表示するには、次のコマンドを使用します:
SELECT table, name, status FROM system.vector_indices
WHERE table = 'test_float_vector'
これにより、ベクトルインデックスの現在のステータスなどの情報が出力されます。ステータスは次のいずれかです:
Built:このステータスは、インデックスが正常に構築され、使用する準備ができていることを示します。InProgress:このステータスは、インデックスが現在構築中または更新中であることを意味します。この間、インデックスは不完全な状態であり、インデックスされていないデータのベクトル検索は力まかせアルゴリズムにフォールバックし、非常に遅くなります。Error:インデックスが構築または使用中にエラーが発生した場合、Errorステータスになります。これは、無効な入力データやシステムの障害など、さまざまな理由によるものです。このステータスの場合、エラーが解決するまで通常は使用できません。
Errorステータスのベクトルインデックスの場合、次のコマンドで失敗理由を表示できます:
SELECT table, name, latest_failed_part, latest_fail_reason
FROM system.vector_indices WHERE status = 'Error'
# 基本的なベクトル検索
ベクトル検索を実行するためには、distance()関数を使用します。この関数は、指定したベクトルと指定した列内のすべてのベクトルデータとの距離を計算し、上位の候補を返します。distance()関数の基本的な構文は以下の通りです:
distance('param1 = value1', 'param2 = value2')(column_name, query_vector)
paramsは、検索固有のパラメータを表します。paramsには、IVFFLATベクトルインデックスの場合のように、インデックス固有のパラメータも含めることができます。これにより、検索の範囲を定義するためにnprobe = 1などを指定できます。column_nameは、検索対象のベクトルデータが含まれる列を指します。query_vectorは検索されるベクトルです。
TIP
- float32ベクトルの配列の場合、クエリベクトルに小数点を含めることが重要です。これにより、
Array(UInt64)型として認識されることを防ぎ、クエリの実行時にエラーが発生することを防ぎます。例えば、float32ベクトルの128D配列は[3.0, 9, ..., 4]の形式です。 - バイナリ文字列ベクトルの場合、他のタイプと比べて表示や入力が容易ではないかもしれませんが、特定の関数の助けを借りて操作することができます。
char()関数を使用してバイナリベクトルを生成します。この関数は、渡された引数の数と同じ長さのバイナリ文字列を返し、各バイトは対応する引数の値を持ちます。例えば、128Dバイナリ文字列ベクトルはchar(128, 254, ... 127, 100)の形式です。unbin()関数を使用してバイナリベクトルを生成します。この関数は、引数の各ペアの二進数を数値として解釈し、その数値で表されるバイトに変換します。例えば、128Dバイナリ文字列ベクトルはunbin('01010...01010')の形式です。unhex()関数を使用してバイナリベクトルを生成します。この関数は、引数の各ペアの16進数を数値として解釈し、その数値で表されるバイトに変換します。例えば、128Dバイナリ文字列ベクトルはunhex('FFEEDDCC...112233')の形式です。
distance()関数は、上位の候補を取得するためにorder byとlimit句とともに使用する必要があります。- order by句のdistance関数の列のソート方向は、ベクトルインデックスのメトリックタイプ(Cosine、IPなど)に対応している必要があります。そうでない場合、エラーが報告されます。メトリックタイプが
IPの場合、ソート方向はDESCである必要があります。
float32ベクトルの配列の検索クエリの典型的な例は次のようになります:
SELECT id, date, label,
distance(data, [3.0, 9, 45, 22, 28, 11, 4, 3, 77, 10, 4, 1, 1, 4, 3, 11, 23, 0, 0, 0, 26, 49, 6, 7, 5, 3, 3, 1, 11, 50, 8, 9, 11, 7, 15, 21, 12, 17, 21, 25, 121, 12, 4, 7, 4, 7, 4, 41, 28, 2, 0, 1, 10, 42, 22, 20, 1, 1, 4, 9, 31, 79, 16, 3, 23, 4, 6, 26, 31, 121, 87, 40, 121, 82, 16, 12, 15, 41, 6, 10, 76, 48, 5, 3, 21, 42, 41, 50, 5, 17, 18, 64, 86, 54, 17, 6, 43, 62, 56, 84, 116, 108, 38, 26, 58, 63, 20, 87, 105, 37, 2, 2, 121, 121, 38, 25, 44, 33, 24, 46, 3, 16, 27, 74, 121, 55, 9, 4]) AS dist
FROM test_float_vector
ORDER BY dist LIMIT 10
このクエリは、test_float_vectorテーブルのベクトル列とクエリベクトル[3.0, 9, ..., 4]の間の距離を返します。ORDER BY dist LIMIT 10句は、上位10件の最も近い結果を返すことを指定しています。
出力:
| id | date | label | dist |
|---|---|---|---|
| 3 | "2024-08-11" | "animal" | 0 |
| 790110 | "2001-10-14" | "person" | 102904 |
| 396372 | "1987-12-15" | "animal" | 108579 |
| 401952 | "1975-08-24" | "animal" | 117388 |
| 603558 | "1999-09-26" | "animal" | 118487 |
| 25589 | "1978-08-29" | "animal" | 119259 |
| 12632 | "2019-02-25" | "animal" | 119662 |
| 800289 | "2000-07-09" | "building" | 119673 |
| 16298 | "1997-03-11" | "animal" | 120011 |
| 395903 | "2020-08-19" | "animal" | 121352 |
クエリの結果は、id、date、label、およびクエリベクトルとの距離を示すdistの3つの列からなるテーブルです。
したがって、バイナリ文字列ベクトルの検索クエリの典型的な例は次のようになります:
SELECT id, date, label,
distance(binary_data, unhex('ABCDEF0123456789ABCDEF0123456789')) AS dist
FROM test_binary_vector
ORDER BY dist LIMIT 10
# フィルター付きのベクトル検索
フィルター付きのベクトル検索では、他の列の値や距離値に基づいて結果を絞り込むことができます。たとえば、次のクエリは、id列が100000より大きい行についてのみ、test_float_vectorテーブルのベクトル列とクエリベクトル[3.0, 9, ..., 4]の間の距離を返します:
SELECT id, date, label,
distance(data, [3.0, 9, 45, 22, 28, 11, 4, 3, 77, 10, 4, 1, 1, 4, 3, 11, 23, 0, 0, 0, 26, 49, 6, 7, 5, 3, 3, 1, 11, 50, 8, 9, 11, 7, 15, 21, 12, 17, 21, 25, 121, 12, 4, 7, 4, 7, 4, 41, 28, 2, 0, 1, 10, 42, 22, 20, 1, 1, 4, 9, 31, 79, 16, 3, 23, 4, 6, 26, 31, 121, 87, 40, 121, 82, 16, 12, 15, 41, 6, 10, 76, 48, 5, 3, 21, 42, 41, 50, 5, 17, 18, 64, 86, 54, 17, 6, 43, 62, 56, 84, 116, 108, 38, 26, 58, 63, 20, 87, 105, 37, 2, 2, 121, 121, 38, 25, 44, 33, 24, 46, 3, 16, 27, 74, 121, 55, 9, 4]) AS dist
FROM test_float_vector
WHERE id > 100000
ORDER BY dist LIMIT 10
出力:
| id | date | label | dist |
|---|---|---|---|
| 790110 | "2001-10-14" | "person" | 102904 |
| 396372 | "1987-12-15" | "animal" | 108579 |
| 401952 | "1975-08-24" | "animal" | 117388 |
| 603558 | "1999-09-26" | "animal" | 118487 |
| 800289 | "2000-07-09" | "building" | 119673 |
| 395903 | "2020-08-19" | "animal" | 121352 |
| 600737 | "1972-08-25" | "animal" | 125027 |
| 790101 | "1990-02-22" | "person" | 129224 |
| 790265 | "2019-05-26" | "building" | 133267 |
| 198290 | "1974-04-22" | "building" | 134178 |
distance値でフィルタリングするには、次のようにWHERE句を使用します:
SELECT id, date, label,
distance(data, [3.0, 9, 45, 22, 28, 11, 4, 3, 77, 10, 4, 1, 1, 4, 3, 11, 23, 0, 0, 0, 26, 49, 6, 7, 5, 3, 3, 1, 11, 50, 8, 9, 11, 7, 15, 21, 12, 17, 21, 25, 121, 12, 4, 7, 4, 7, 4, 41, 28, 2, 0, 1, 10, 42, 22, 20, 1, 1, 4, 9, 31, 79, 16, 3, 23, 4, 6, 26, 31, 121, 87, 40, 121, 82, 16, 12, 15, 41, 6, 10, 76, 48, 5, 3, 21, 42, 41, 50, 5, 17, 18, 64, 86, 54, 17, 6, 43, 62, 56, 84, 116, 108, 38, 26, 58, 63, 20, 87, 105, 37, 2, 2, 121, 121, 38, 25, 44, 33, 24, 46, 3, 16, 27, 74, 121, 55, 9, 4]) AS dist
FROM test_float_vector
WHERE dist < 110000
ORDER BY dist LIMIT 10
このクエリは、test_float_vectorテーブルのベクトル列とクエリベクトル[3.0, 9, ..., 4]の間の距離を返しますが、距離が110000未満の行についてのみです。
出力:
| id | date | label | dist |
|---|---|---|---|
| 3 | "2024-08-11" | "animal" | 0 |
| 790110 | "2001-10-14" | "person" | 102904 |
| 396372 | "1987-12-15" | "animal" | 108579 |
# 複数のベクトル検索
注意
この機能は、DBバージョンv1.8以上でのみ利用可能です。
複数のdistance()関数をベクトル検索クエリで使用することができる複数のベクトル検索機能です。複数のdistance()関数のトップ候補は、部分および行IDに基づいて組み合わせられます。distance()関数の結果タイプはFloat32です。したがって、2つのベクトルvec1とvec2を持つ行の場合、トップ候補には1つのベクトルのみが表示され、もう1つのベクトルのdistance()値はNaNになります。 典型的な複数のベクトル検索クエリは次のようになります:
SELECT id, date, label, distance(vec1, [3.0, 9, 45, 22, 28, 11, 4, 3, 77, 10, 4, 1, 1, 4, 3, 11, 23, 0, 0, 0, 26, 49, 6, 7, 5, 3, 3, 1, 11, 50, 8, 9, 11, 7, 15, 21, 12, 17, 21, 25, 121, 12, 4, 7, 4, 7, 4, 41, 28, 2, 0, 1, 10, 42, 22, 20, 1, 1, 4, 9, 31, 79, 16, 3, 23, 4, 6, 26, 31, 121, 87, 40, 121, 82, 16, 12, 15, 41, 6, 10, 76, 48, 5, 3, 21, 42, 41, 50, 5, 17, 18, 64, 86, 54, 17, 6, 43, 62, 56, 84, 116, 108, 38, 26, 58, 63, 20, 87, 105, 37, 2, 2, 121, 121, 38, 25, 44, 33, 24, 46, 3, 16, 27, 74, 121, 55, 9, 4]) AS dist1,
distance(vec2, [3.0, 9, 45, 22, 28, 11, 4, 3, 77, 10, 4, 1, 1, 4, 3, 11, 23, 0, 0, 0, 26, 49, 6, 7, 5, 3, 3, 1, 11, 50, 8, 9, 11, 7, 15, 21, 12, 17, 21, 25, 121, 12, 4, 7, 4, 7, 4, 41, 28, 2, 0, 1, 10, 42, 22, 20, 1, 1, 4, 9, 31, 79, 16, 3]) AS dist2
FROM test_multiple_vectors
ORDER BY dist1 + dist2
LIMIT 10;
- ベクトル検索の選択クエリは、order byおよびlimit句と組み合わせてトップ候補を取得するために使用する必要があります。
- distance()の値にNaNが含まれる場合、ifNotFinite(dist1, <default_value>)のような式を使用して、NaN値に適切なデフォルト値を提供できます。
# ベクトルインデックスの設定オプションの説明
ベクトルインデックスには、インデックス作成パラメータと検索パラメータの2種類のパラメータがあります。
インデックス作成パラメータは、インデックス作成時に指定されます。たとえば、
ALTER TABLE [db.]table_name
ADD VECTOR INDEX index_name column_name
[TYPE index_type
(
'creation_param1 = value1',
'creation_param2 = value2',
...
)]
検索パラメータは、検索中に指定されます。例えば、
SELECT
id,
distance('search_param1 = value1', 'search_param2 = value2')(column_name, query_vector) as dist
FROM [db.]table_name
ORDER BY dist LIMIT 10
# 一般的なインデックス作成パラメータ
以下のパラメータは、任意のタイプのベクトルインデックスの作成に使用できます。
metric_type: このパラメータは、ベクトル検索で使用される距離メトリックを決定します。- Float32ベクトルの配列の場合、3つのオプションが利用可能で、
L2がデフォルト値です。L2: L2メトリック、別名ユークリッド距離。Cosine: コサイン距離は、コサイン類似度に基づいています。コサイン距離の公式は次のように計算されます:
コサイン類似度は、距離値を1から引くことで得られます。IP: 内積(IP)メトリック。IPメトリックを使用する場合は、より高いIP値がより大きな類似性を示すため、ORDER BY ... DESCを使用する必要があります。
- 二進数文字列ベクトルの場合、1つのオプションが利用可能で、
Hammingがデフォルト値です。Hamming: 二つの同じ長さのベクトル間のハミング距離は、対応する位置で異なる記号の数です。Jaccard: ジャカード距離は非類似性を測定します。ジャカード距離の公式は次のように計算されます:
ジャカード係数は、距離値を1から引くことで得られます。
- Float32ベクトルの配列の場合、3つのオプションが利用可能で、
# ScaNN / MSTG / BinaryMSTG パラメータ
ScaNN は、Google が高次元ベクトル空間での高速かつスケーラブルな最近傍探索のために開発したアルゴリズムです。
MyScaleが開発したMulti-Scale Tree Graph(MSTG)アルゴリズムは、標準的なベクトル検索操作とフィルタリングされたベクトル検索操作の両方において、高いデータ密度と高いパフォーマンスを提供するために設計された独自のソリューションです。
インデックス作成パラメータ:
ScaNN、MSTG、BinaryMSTG は、インデックスの作成中に metric_type 以外のパラメータを受け付けません。
検索パラメータ:
alpha = float: このパラメータは、検索操作の精度を制御します。値が高いほど検索はより正確になりますが、QPSは低下します。デフォルト値は3で、有効な範囲は1から4です。
# FLAT / BinaryFLAT パラメータ
FLAT および BinaryFLAT は、ベクトルインデックスの最も単純な形態であり、追加の最適化パラメーターなしで生データに基づいて距離を直接計算します。プロトタイピングや検索結果の正確性を確保するためには便利ですが、比較的遅いパフォーマンスのため、本番環境での使用はお勧めできません。
# IVFFLATパラメータ
IVFFLATは、クラスタリングを使用してベクトルをより効率的に検索するために、ベクトルをより小さなクラスタに分割する階層的なインデックスです。
インデックス作成パラメータ:
ncentroids = int: すべてのベクトルデータを分割するクラスタの数を決定します。ncentroidsの値が大きいほど、テーブルの構築時間が遅くなります。デフォルト値は1024です。
検索パラメータ:
nprobe = int: 検索操作中に検索するクラスタの数を指定します。値が大きいほど検索は遅くなりますが、精度が向上します。デフォルト値は1です。
推奨されるパラメータの値:
ncentroidsには、データ量の平方根に近い値を選ぶことを推奨します。値が大きすぎるとパフォーマンスに影響が出る可能性があるためです。nprobeには、ncentroidsの0.1-10%の値を推奨します。
# IVFPQパラメータ
インデックス作成パラメータ:
ncentroids = int:IVFFLATを参照してください。M = int: 元のベクトルの次元をMに削減します。Mは元のベクトルの次元で割り切れる必要があります。デフォルト値は16です。bit_size = int: 元のベクトルを置き換えるために使用されるProduct Quantization(PQ)エンコーディングテーブルのサイズを指定します。有効な値は4の倍数で、デフォルト値は8です。
検索パラメータ:
nprobe = int:IVFFLATを参照してください。
推奨されるパラメータの値:
ncentroidsとnprobeの推奨値は、IVFFLATと同様です。PQの圧縮率は、(bit_size * M) / (original_dimension * original_element_size)で計算されます。128次元のfloat32ベクトルの場合、M = 16、bit_size = 8の場合、対応する圧縮率は(16*8)/(128*32) = 1/32です。圧縮率が極端に高いと、検索結果の精度に大きな影響を与える可能性があるため、この問題を回避するためにbit_sizeを8に保ち、Mを元の次元の1/4以内に保つことを推奨します。
# IVFSQ パラメータ
インデックス作成パラメータ:
ncentroids = int:IVFFlatを参照してください。bit_size = string: 許容される値は8bit,6bit,4bit,8bit_uniform,8bit_direct,4bit_uniform,QT_fp16で、デフォルト値は8bitです。
スカラー量子化(SQ)アルゴリズムは、各ベクトル次元を圧縮しながら次元数を保持するために使用されます。bit_size を 8 に設定すると、圧縮率は約 25% になります。アルゴリズムの精度は、8bit_direct、8bit_uniform、8bit の順に高くなりますが、インデックスの構築速度は精度に反比例します。8bit_direct は、static_cast を使用して float を uint_8 に変換します。8bit_uniform は、すべての float 値を均等に 256 個のビンに分割します。8bit は、各次元を 256 個のビンに均等に分割します。4bit_uniform は、データを 16 個のビンに分割して量子化します。QT_fp16 は、半精度浮動小数点数を使用する SQ アルゴリズムのバリエーションであり、詳細はリンク https://gist.github.com/rygorous/2156668 (opens new window) で確認できます。
検索パラメータ:
nprobe = int:IVFFlatを参照してください。
# HNSWFLAT パラメータ
階層型ナビゲーション可能な小世界(HNSW)アルゴリズムは、高次元空間において与えられたクエリポイントの最近傍点を迅速に見つけるための近似最近傍探索アルゴリズムの一種です。これは、データポイントを多段階のグラフデータ構造に組織化することで実現されます。HNSW アルゴリズムは、「小世界」ネットワークの原理を利用して、グラフをナビゲートし、クエリポイントに最も近いデータポイントを効率的に見つけます。大規模なデータセットや高次元空間において、高いパフォーマンスとスケーラビリティで知られています。
インデックス作成パラメータ:
m = int: このパラメータは、HNSW ダイアグラム内の各データポイントの近傍数を決定し、インデックスの品質に影響を与えます。mを大きくすると、検索結果の精度が向上しますが、インデックスの構築時間も増加します。デフォルト値は 16 です。ef_c = int: このパラメータは、インデックスの作成時に HNSW が使用する優先度キューのサイズを決定し、インデックスの品質に影響を与えます。ef_cを大きくすると、検索結果の精度が向上しますが、インデックスの構築時間も増加します。デフォルト値は 100 です。
検索パラメータ:
ef_s = int: このパラメータは、検索操作中に HNSW が使用する優先度キューのサイズを決定します。ef_sを大きくすると、検索結果の精度が向上しますが、検索時間も増加します。デフォルト値は 50 です。
推奨されるパラメータ値:
一般的には、m を 8-128 の範囲で設定し、ef_c を 50-400 の範囲で設定することを推奨します。ef_c を倍にすると、インデックスの構築時間がほぼ倍になります。ef_s の値は検索要件に応じて調整し、ef_c と同じ値の範囲を使用することを推奨します。低遅延の要件がある場合は、より低い値を選択することができます。
# HNSWSQ パラメータ
インデックス作成パラメータ:
検索パラメータ:
ef_s = int:HNSWFLATを参照してください。
推奨されるパラメータ値:
bit_size の選択については、IVFSQを参照し、その他のパラメータについてはHNSWFLATを参照してください。
# パフォーマンスチューニングのアドバイス
一般的に、パフォーマンスを最適化するために MSTG/BinaryMSTG インデックスとインデックス作成のデフォルト値の使用を推奨します。検索時には、希望するスループットと精度に基づいて alpha 値を調整できます。
MyScaleでは、データは自動的に複数のパーツに分割され、内部的には各パーツごとに1つのベクトルインデックスが作成されます。最適なパフォーマンスを得るためには、ベクトルインデックスを作成する前にテーブルを1つのデータパーツに最適化することをおすすめします。次のコマンドを使用して、テーブルを最適化することができます。
OPTIMIZE TABLE test_vector FINAL
したがって、操作の推奨される順序は次のとおりです。
CREATE TABLE ...を使用してテーブルを作成します。INSERT INTO ...を使用してデータを挿入します。- テーブルを最適化します。
ALTER TABLE ... ADD VECTOR INDEXを使用してベクトルインデックスを作成します。- ベクトルインデックスの構築が完了するのを待ちます。
- 検索を開始します。
インデックス作成後にテーブルを最適化すると、多くのメモリを消費する可能性があることに注意してください。したがって、インデックス作成後にテーブルを最適化しないでください。