Spanner Omni ベクトル検索の概要

Spanner Omni のベクトル検索は、高次元ベクトル データに対するセマンティック検索と類似性マッチングを可能にする、高パフォーマンスの組み込み機能です。Spanner Omni は、トランザクション データベース内にベクトル エンベディングを直接保存してインデックス登録することで、個別のベクトル データベースと複雑な ETL(抽出、変換、読み込み)パイプラインを排除します。

このドキュメントのトピックは、Spanner に適用されるのと同じ方法で Spanner Omni に適用されます。

ベクトル検索では、データを数値ベクトル(エンベディング)として表現することで、意味的に類似したアイテムを見つけることができます。Spanner Omni は、次の 2 つの主な検索方法をサポートしています。

  • k 近傍法(KNN): クエリとデータセット内のすべてのベクトルの距離を計算して、正確な検索を実行します。再現率が最も高くなりますが、大規模なデータセットでは計算コストが高くなる可能性があります。

  • 近似最近傍(ANN): ベクトル インデックスを使用して、大規模なデータセット全体で一致を高速に検索します。精度(再現率)が若干低下する代わりに、速度とスケーラビリティが向上します。

ベクトル検索は、他の機能と組み合わせると特に強力です。

組み合わせ メリット
SQL フィルタリングを使用したベクトル検索 ベクトル検索とフィルタを効率的に組み合わせる(例: 「カテゴリが靴で価格が 100 未満の類似画像を検索する」)。
ベクトル検索 + 全文検索 Reciprocal Rank Fusion(RRF)を使用してセマンティック類似性とキーワードの精度を組み合わせ、検索の関連性を高めます。
ベクトル + グラフ ベクトル検索を使用してプロパティ グラフ内の関連するエントリ ポイント(ノード)を見つけ、複雑な関係をトラバースします。

詳細については、Spanner ドキュメントの Spanner ベクトル検索の概要をご覧ください。

Spanner Omni は、組み込みの距離関数を使用した K 最近傍(KNN)検索をサポートしています。ベクトル エンベディングを入力パラメータとして指定して、N 次元空間内で最も近いベクトルを見つけることができます。

次の距離関数を使用できます。

  • COSINE_DISTANCE(): 2 つのベクトル間の角度のコサインを測定します

  • EUCLIDEAN_DISTANCE(): 2 つのベクトル間の最短直線距離を測定します。

  • DOT_PRODUCT(): 角度のコサインに、ベクトルの大きさの積を掛けます(正規化されたデータに最適)。

詳細については、Spanner ドキュメントの K 近傍法を探索してベクトル類似性検索を行うをご覧ください。

最適なベクトル距離関数を選択する

適切な距離関数を選択するかどうかは、データとエンベディングの生成に使用されるモデルによって異なります。

関数 説明 類似度の増加との関係
ドット積 角度のコサインに、対応するベクトルの大きさを掛けます。 増加
コサイン距離 2 つのベクトル間の角度のコサイン(1 - コサイン類似度)を測定します。 減少
ユークリッド距離 2 つのベクトル間の直線距離を測定します。 減少

エンベディングが正規化されている場合(大きさ = 1.0)、通常は DOT_PRODUCT() が効率的な選択肢です。正規化されていないデータの場合は、COSINE_DISTANCE() または EUCLIDEAN_DISTANCE() を試して、ユースケースでより良い結果が得られる方を判断します。

詳細については、Spanner ドキュメントのベクトル距離関数から選択するをご覧ください。

近似最近傍探索(ANN)

ANN 検索は、正確な KNN 検索の処理速度が遅すぎたり、費用が高すぎたりするような非常に大規模なデータセット向けに設計されています。ベクトル インデックスを使用して、再現率の低下を最小限に抑えながら高速な結果を提供します。

専用のコンピューティング ワーカーがない場合、Spanner Omni の ANN 検索は、長さが最大 128 ディメンションのベクトルに対して、最大 100 万個のベクトルのデータセットをサポートします。ベクトルの次元数が多いほど、サポートされるベクトル数は比例して減少します。Spanner Omni は、ワーカーをデプロイしてベクトル インデックスを構築する際に、より大きなテーブルをサポートします。詳細については、ベクトル インデックスの作成と管理をご覧ください。

ANN 検索を実行するには、APPROX_COSINE_DISTANCE()、APPROX_EUCLIDEAN_DISTANCE()、APPROX_DOT_PRODUCT() などの近似距離関数を使用します。これらの関数には次のものが必要です。

  • エンベディング列の既存のベクトル インデックス。

  • 近似距離関数を使用する ORDER BY 句。

  • 結果の数を指定する LIMIT 句。

詳細については、Spanner ドキュメントの近似最近傍(ANN)を検索してベクトル エンベディングをクエリするをご覧ください。

ベクトル インデックスを作成して管理する

ベクトル インデックスを作成するときに、エンベディング列の vector_length を指定し、STORING 句を使用してフィルタリングを高速化するための追加の列を含めます。

ベクトル インデックスを作成する例を次に示します。

CREATE VECTOR INDEX INDEX_NAME
  ON TABLE_NAME(EMBEDDING_COLUMN)
  OPTIONS (distance_type = 'DISTANCE_TYPE', tree_depth = 2, num_leaves = 1000);

詳細については、Spanner ドキュメントのベクトル インデックスの作成と管理をご覧ください。

近似最近傍(ANN)の制限を超える大規模なテーブルにベクトル インデックスを構築するには、Spanner Omni サーバーから処理をオフロードするための専用のコンピューティング ワーカーが必要です。詳細については、ワーカーをデプロイして管理するをご覧ください。

ベクトル インデックスの作成時にサンプリングを使用する

数千万行以上のテーブルなど、大規模なデータセットの場合は、サンプリング率を指定することで、ベクトル インデックスの作成時間を短縮できます。初期インデックス ツリーを構築するときに、CREATE VECTOR INDEX ステートメントの clustering_sampling_percentage オプションを使用して、データセットのサブセットをサンプリングします。

一般的なガイドラインとして、リーフあたり少なくとも 50 個のサンプリングされた行を目標にしてください。たとえば、1,000 万行のデータセットに 10,000 個のリーフがある場合、5% のサンプリング レート(clustering_sampling_percentage = 5)では、次の例に示すように、50 万行(リーフあたり 50 行)がサンプリングされます。

CREATE VECTOR INDEX VectorIndex
  ON BaseTable(Embedding)
  WHERE Embedding IS NOT NULL
  OPTIONS (
    tree_depth = 3,
    num_leaves = 10000,
    num_branches = 100,
    leaf_scatter_factor = 32,
    distance_type = 'COSINE',
    min_branch_splits = 10,
    min_leaf_splits = 10,
    clustering_sampling_percentage = 5
  );

サンプリングなしでデータセット全体にインデックスを構築する場合と比較して、サンプリングでは、同じ目標再現率に対してクエリ レイテンシとクエリあたりの CPU 使用率が増加します。サンプリング率を上げると、インデックスの作成時間は長くなりますが、クエリ レイテンシとクエリあたりの CPU コストは削減されます。インデックス作成に使用できるコンピューティング リソースに基づいて、インデックス作成時間とクエリ パフォーマンスのバランスが取れるサンプリング率を選択します。

ベクトル インデックス登録のベスト プラクティス

高い検索パフォーマンスと再現率を維持するには:

  • インデックス オプションを調整する: データサイズとパフォーマンス要件に基づいて num_leaves と num_leaves_to_search を調整します。

  • 定期的に再構築する: ベクトルの分布が時間の経過とともに大きく変化する場合は、インデックスを再構築します。

  • フィルタリングを効果的に使用する: 検索効率を向上させるため、頻繁にフィルタリングされる列をインデックスに保存します。

詳細については、Spanner ドキュメントのベクトル インデックス登録のベスト プラクティスをご覧ください。