OceanBaseデータベースは、さまざまなアルゴリズムを持つベクトルインデックスを提供しており、ユーザーは使用シナリオに応じて適切なインデックスタイプを選択できます。
HNSW と IVF のどちらを選ぶ?
OceanBase の密ベクトルインデックスは大きく 2 つのカテゴリに分類されます:
- グラフベースの HNSW シリーズインデックス:HNSW、HNSW_SQ、HNSW_BQ
- ディスクベースの IVF シリーズインデックス:IVF、IVF_PQ
これら 2 つのインデックスタイプはそれぞれ異なる特長を持っています。HNSW シリーズインデックスは通常、より高いクエリパフォーマンスを提供しますが、常駐メモリを多く消費します。一方、IVF シリーズインデックスはキャッシュが十分な場合に優れたパフォーマンスを発揮し、常駐メモリに依存せずに動作できます。しかし、HNSW と IVF の選択はメモリの観点だけではなく、ビジネスシナリオ、データ規模、パフォーマンス指標、リソース制約など、複数の側面を総合的に評価する必要があります。以下では、その主な違いを詳しく比較し、選択のポイントを提示します。
主な違いの比較
比較項目 |
HNSWシリーズ |
IVFシリーズ |
|---|---|---|
| ストレージ方式 | メモリベースのグラフ構造インデックス | ディスクベースのインデックス |
| メモリ使用量 | 完全にメモリにロードする必要があり、メモリ使用量が高い | 常駐メモリを使用しない場合があり、メモリ使用量が低い |
| クエリパフォーマンス(QPS) | 非常に高く、ミリ秒単位の応答 | 比較的高く、キャッシュが十分な場合はHNSWに近づく |
| 召回率 | 高く、最大99%に達する | 比較的高く、HNSWよりわずかに低いが、パラメータチューニングで調整可能 |
| 構築速度 | 比較的遅く、グラフ構造の構築が必要 | 比較的速く、クラスタリングアルゴリズムに基づく |
| 適用データ量 | 百万単位から億単位 | 百万単位から十億単位 |
| コスト | メモリコストが高い | ストレージコストが低く、大規模データに適している |
| リアルタイム性 | リアルタイムDML操作をサポートする | リアルタイムDML操作をサポートする |
意思決定フローチャート
説明
- インデックスタイプを選択する前に、ベクトルインデックスのメモリ管理 を参照してメモリ使用量を見積もる必要があります。
- 意思決定フローチャートにおける選択の推奨事項はすべて、1024 次元のベクトルを基準としています。実際の次元が異なる場合は、必要なリソースを比率に応じて近似的に換算できます。
- 意思決定フローチャートは主にメモリコストの観点から、インデックスタイプの選択を支援します。
- テナントのメモリが十分であっても、必ずしも HNSW などの最高仕様のインデックスを選択するわけではありません。極めたパフォーマンスが求められる場合は、HNSW_SQ などのコストパフォーマンスに優れたオプションを検討できます。

注意
ここでは一般的なシナリオの意思決定プロセスの一部を挙げています。上記の方法で判断できない場合や、その他の要件がある場合は、OceanBase テクニカルサポートにお問い合わせください。
パーティションテーブルを使用するかどうか?
パーティションテーブルを使用する主な目的は、大量データを扱うシナリオを解決することです。次に、クエリ条件がパーティションキーとして利用できる場合、パーティションプルーニングによりクエリ性能を向上させることができます。以下の2つのシナリオでは、パーティションテーブルの使用を推奨します:
- データ量が数千万または億単位以上に達する場合:データ量が非常に大きい場合、パーティションテーブルを使用するとデータを複数のパーティションに分散し、各パーティションに独立したインデックスを構築することで、1回のクエリ負荷を軽減し、全体のクエリ性能を向上させることができます。
- クエリ条件において、明確なスカラーカラムをパーティションプルーニングに利用できる場合:例えば、
labelフィールドが常にWHERE条件に含まれる場合、labelをパーティションキーとしてパーティションテーブルを作成し、パーティションプルーニングによってクエリ対象のパーティション数を削減することを検討できます。
具体的な使用の推奨事項は以下の通りです:
パーティションの分割
ベクトルインデックスを使用する場合、パーティション数は多くすべきではありません。スカラーインデックスとは異なり、ベクトルインデックス(例:HNSW)では、同じ構成でインデックスサイズを100万ベクトルから200万ベクトルに増やしても、TopKクエリの計算コストは顕著に増加しません。そのため、パーティションプルーニングが利用できない場合、過度に多いパーティションはかえってパフォーマンスを低下させる可能性があります。また、単一のパーティションが大きすぎると、インデックスの再構築時間が長くなるだけでなく、スカラー条件との結合クエリ時の効率にも影響します。
以上のことから、各パーティション内のデータ量を2,000万件以下に制御し、パーティションプルーニングをサポートするフィールドを優先的にパーティションキーとして選択することを推奨します。
アルゴリズムの選択
大量データの場合は、HNSW_BQまたはIVF_PQインデックスを選択することを推奨します。他のインデックスを使用する必要がある場合は、以下のメモリ使用量のセクションを参照して見積もりを行ってください。
メモリ使用量
HNSW_BQ
HNSW_BQインデックスについては、テナントメモリ > HNSW_BQクエリ時の総メモリ使用量 + 単一パーティションのHNSW_SQインデックス使用量 を推奨します。メモリの見積もり手順は以下のとおりです:
- まず、
INDEX_VECTOR_MEMORY_ADVISOR関数を使用して、HNSW_BQおよびHNSW_SQインデックスの構築時およびクエリ時の推奨メモリ値を計算します。 - 上記ツールで得られた推奨メモリ値に基づき、テナントが必要とするメモリの合計量を計算し決定します。
例えば、1億件の1024次元ベクトルデータがあり、10個のパーティション(各パーティション約1000万ベクトル)を使用する場合、上記の手順に従って具体的な計算過程は以下のとおりです:
-- REFINE_TYPE=SQ8を指定することで、HNSW_BQインデックスの構築時およびクエリ時の推奨メモリ値を直接正確に取得できます。
-- HNSW_SQインデックスの使用量を別途計算する必要はありません。これは、HNSW_BQが構築時にデフォルトでSQ8量化アルゴリズムを使用して構成されるためです。
-- refine_type=sq8を指定すると、関数はそのインデックスの構築に必要なSQ8量化ベクトルのメモリを自動的に計算に含めます。
-- HNSW_BQインデックスの推奨メモリ値は74.6GB、クエリ時のメモリ使用量は57.4GBです。ここでは推奨メモリ値を採用します。
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
-- したがって、テナントメモリの設定は179GBを推奨します。
IVFシリーズ
IVFおよびIVF_PQインデックスについては、テナントメモリ > 単一パーティション構築メモリ + すべてのパーティション常駐メモリの合計 を推奨します。例えば、1億件のデータを10個のパーティションに分割する場合、各パーティションは約1000万件のベクトルとなり、単一パーティションで構築する場合は約2.7GBのメモリが必要です。クエリ時には、10個のパーティションにまたがるIVF_PQインデックス全体で約1.1GB(110MB/パーティション)が常駐します。したがって、最低でも約3GBのメモリを構成する必要があります。この基準を踏まえ、適宜余裕を持たせることを推奨し、6GBのメモリ構成を推奨します。その他のデータ量のシナリオについても、上記の方法で見積もることができます。
インデックスの構築とクエリパラメータ
インデックスの構築とクエリパラメータは、単一パーティションの最大データ量を基準に設定することを推奨します。詳細については、後述のインデックスパラメータの推奨事項を参照してください。
パフォーマンスとリコール率
- クエリ条件が単一のパーティションに絞り込める場合:パフォーマンスとリコール率は単一パーティションの場合と同じです。詳細は、後述のデータ量に応じた詳細説明のセクションを参照してください。
- 単一のパーティションに絞り込めない場合:QPSは、各OBServerノード上のパーティション数に応じて比例して推定できます(例:単一ノードに3つのパーティションがある場合、QPSは単一パーティションの約1/3)。ただし、パーティションをまたいだクエリではより多くの候補結果がマージされるため、実際のリコール率は通常、単一パーティションの場合よりも高くなります。
インデックスパラメータの推奨事項
HNSWシリーズ
同じシリーズのインデックスでも、データ量によって推奨されるインデックス構築とクエリパラメータは異なります。このセクションでは、百万件および千万件のデータ量における、768次元ベクトルに対するHNSW/HNSW_SQ/HNSW_BQインデックスの推奨設定を参考までに示します。億単位のベクトルデータについては、本記事の後半の章を参照し、IVF_PQインデックス、またはパーティションテーブル内のHNSW_BQインデックスを選択してください。
注意
データ量が増加する見込みのあるシナリオでは、最終的なデータ量に基づいてパラメータを設定することを推奨します。
注意
HNSW_BQは高圧縮率の量子化アルゴリズムであり、低次元ベクトルにおける再現率の上限が低くなる可能性があります。パフォーマンスの低下を避けるため、HNSW_BQは512次元以上のベクトルで使用することを推奨します。
シナリオ |
インデックスタイプ |
パラメータの推奨値 |
|---|---|---|
| 最高の再現率 (メモリ使用量最大) |
HNSW | 100万件データ量:m = 16、ef_construction = 200、ef_search = 100、その他のパラメータはデフォルト |
| 最高のパフォーマンス (メモリ使用量少なめ) |
HNSW_SQ | 100万件データ量:m = 16、ef_construction = 200、ef_search = 100、その他のパラメータはデフォルト 1000万件データ量:m = 32、ef_construction = 400、ef_search = 350、その他のパラメータはデフォルト |
| 最適なコストパフォーマンス (メモリ使用量が少なく、パフォーマンスが良い) |
HNSW_BQ | 100万件データ量:m = 16、ef_construction = 200、ef_search = 100、その他のパラメータはデフォルト 1000万件データ量:m = 32、ef_construction = 400、ef_search = 1000、refine_k = 10、その他のパラメータはデフォルト 億単位データ量:パーティションテーブルを使用、m = 32、ef_construction = 400、ef_search = 1000、refine_k = 10、その他のパラメータはデフォルト |
100万件データ量の詳細説明
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の再現率時の3分の1まで低下します。また、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)
数千万規模データの詳細説明
1,000万件の768次元ベクトルデータを例に(上表の構築パラメータを使用)、メモリ使用量と再現率のチューニングについて補足します。
メモリ使用量:
インデックスタイプ |
推奨テナントメモリ |
説明 |
|---|---|---|
| HNSW | 160 GB | ベクトルインデックスのメモリサイズの推奨値は76.3GBです。 |
| HNSW_SQ | 48 GB | ベクトルインデックスのメモリサイズの推奨値は22.6GBです。 |
| HNSW_BQ | 48 GB | HNSW_BQインデックスは構築時に高精度なベクトルを使用する必要があります。HNSW_BQはデフォルトでインデックス構築中のキャッシュとしてHNSW_SQを使用します。そのため、非パーティションテーブルでは、HNSW_BQが必要とするメモリはHNSW_SQと同じです。構築完了後、HNSW_BQインデックスは約5.4GBのメモリしか占有しません。 |
再現率のチューニング:
ef_search および refine_k(HNSW_BQのみ)パラメータを調整することで、より多くのベクトル計算を行い再現率を向上させることができますが、それに伴いクエリ性能は低下します。異なるTopNにおいて、パラメータを下表の推奨値に設定できます。さらに再現率を向上させる必要がある場合は、パラメータ値を大きく設定してください。
注意
再現率はデータの特徴と直接的な関係があります。下表は、768次元標準データセットにおいて、再現率が約0.95に達するための推奨値です。
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において、パラメータを下表の推奨値に設定できます。さらに再現率を向上させる必要がある場合は、パラメータ値を大きく設定することができます。
注意
再現率はデータの特性と直接的な関係があります。下表は、768次元標準データセットにおいて、再現率が約0.95に達するための推奨値です。
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.5MBの場合、10個のパーティションがあれば、総常駐メモリは約10.5 × 10 = 105MBとなります。
インデックスタイプ |
インデックスパラメータ |
メモリ使用量(構築時/常駐時) |
|---|---|---|
| IVF | distance=l2, nlist=3000 | 2.7 GB/ 10.5 * 10 MB |
| IVF_PQ | distance=l2, nlist=3000, m=384 | 4.0 GB/ 1.3 * 10 GB |
| IVF_PQ | distance=cosine, nlist=3000, m=384 | 2.7 GB/ 11.4 * 10 MB |
表内の構築コストは、インデックス作成時に一時的に使用されるメモリを示し、構築完了後にこのメモリは解放されます。常駐コストは、インデックス構築完了後、IVFベクトルインデックスが継続的に使用するメモリを指します。
リコール率の調整:
nprobesパラメータを調整することで、より多くのベクトル計算を行いリコール率を向上させることができますが、それに伴いクエリ性能は低下します。異なるTopNにおいて、パラメータを下表の推奨値に設定できます。さらにリコール率を向上させる必要がある場合は、パラメータ値を大きく設定することができます。
パーティションテーブルの場合、各パーティションが独立してIVFインデックスクエリを実行するため、ユーザーがクエリ時に複数のパーティションにまたがる場合、各パーティションから個別にTopN結果を取得し、すべてのパーティションの結果を集計・再ソートします。これにより、全体の検索精度が向上するだけでなく、実際のリコール率は通常、単一パーティションの場合よりも高くなります。そのため、マルチパーティションテーブルでは、nprobesパラメータの設定を適切に下げることで、単一パーティションテーブルと同等のリコール率を得ることができます。
注意
リコール率はデータ特性と直接的な関係があります。下表は、768次元標準データセットにおいて、リコール率が約0.95に達するための推奨値です。
TopN |
nprobes |
|---|---|
| Top10 | 1 |
| Top100 | 10 |
関連ドキュメント
- パラメータの詳細説明とチューニングについては、HNSWインデックスおよびIVFインデックスを参照してください。