このページでは、ANN 距離関数を使用して近似最近傍(ANN)を検索し、ベクトル エンベディングをクエリする方法について説明します。
データセットが小さい場合は、k 近傍法(KNN)を使用して、正確な k 近傍ベクトルを検索できます。ただし、データセットのサイズが大きくなるにつれて、KNN 検索のレイテンシとコストも増加します。ANN を使用すると、レイテンシと費用を大幅に削減しながら、近似 k 最近傍を検索できます。
ANN 検索では、近似距離が計算され、データセット内のすべてのベクトルが検査されない可能性があるため、返される k 個のベクトルは真の上位 k 近傍ではありません。上位 k 近傍にないベクトルが返されることがあります。これは「再現損失」と呼ばれます。許容できる再現損失の量はユースケースによって異なりますが、ほとんどの場合、データベースのパフォーマンスを改善するために再現率を多少犠牲にすることは許容されるトレードオフです。
Spanner でサポートされている近似距離関数の詳細については、次の GoogleSQL リファレンス ページをご覧ください。
ベクトル エンベディングのクエリ
Spanner は、ベクトル インデックスを使用して近似最近傍(ANN)ベクトル検索を高速化します。ベクトル インデックスを使用して、ベクトル エンベディングをクエリできます。ベクトル エンベディングをクエリするには、まずベクトル インデックスを作成する必要があります。次に、3 つの近似距離関数のいずれかを使用して ANN を見つけることができます。
近似距離関数を使用する際の制限事項は次のとおりです。
- 近似距離関数は、エンベディング列と定数式(パラメータやリテラルなど)間の距離を計算する必要があります。
- 近似距離関数の出力を
ORDER BY
句で唯一の並べ替えキーとして使用し、ORDER BY
の後にLIMIT
を指定する必要があります。 - クエリで、インデックスに登録されていない行を明示的に除外する必要があります。ほとんどの場合、テーブル定義で列がすでに
NOT NULL
としてマークされている場合を除き、クエリにベクトル インデックス定義に一致するWHERE <column_name> IS NOT NULL
句を含める必要があります。
制限事項の詳細なリストについては、近似距離関数のリファレンス ページをご覧ください。
例
DocContents
バイト列の事前計算されたテキスト エンベディングの DocEmbedding
列と、null になる可能性のある他のソースから入力された NullableDocEmbedding
列を含む Documents
テーブルについて考えてみます。
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING(1024),
DocContents BYTES(MAX),
DocEmbedding ARRAY<FLOAT32> NOT NULL,
NullableDocEmbedding ARRAY<FLOAT32>,
WordCount INT64
) PRIMARY KEY (UserId, DocId);
[1.0, 2.0, 3.0]
に最も近い 100 個のベクトルを検索するには:
SELECT DocId
FROM Documents
WHERE WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
エンベディング列が null 値を許容する場合:
SELECT DocId
FROM Documents
WHERE NullableDocEmbedding IS NOT NULL AND WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
次のステップ
Spanner のベクトル インデックスの詳細を確認する。
GoogleSQL の
VECTOR INDEX
ステートメントの詳細を確認する。ベクトル インデックスのベスト プラクティスの詳細を確認する。
Spanner ベクトル検索を使ってみるで、ANN の使用例を確認する。