Questa pagina spiega come creare e gestire gli indici vettoriali Spanner, che utilizzano la ricerca approssimativa del vicino più prossimo (ANN) e strutture basate su alberi per accelerare le ricerche di similarità vettoriale nei tuoi dati.
Spanner accelera le ricerche vettoriali approssimative del vicino più prossimo (ANN) utilizzando un indice vettoriale specializzato. Questo indice sfrutta Scalable Nearest Neighbor (ScaNN) di Google Research, un algoritmo per la ricerca dei vicini più prossimi altamente efficiente.
L'indice vettoriale utilizza una struttura ad albero per partizionare i dati e facilitare ricerche più rapide. Spanner offre configurazioni ad albero a due e tre livelli:
- Configurazione ad albero a due livelli: i nodi foglia (
num_leaves
) contengono gruppi di vettori strettamente correlati insieme al loro centroide corrispondente. Il livello radice è costituito dai centroidi di tutti i nodi foglia. - Configurazione ad albero a tre livelli: simile nel concetto a un albero a due livelli, ma
introduce un ulteriore livello di ramificazione (
num_branches
), da cui i centroidi dei nodi foglia vengono ulteriormente partizionati per formare il livello radice (num_leaves
).
Spanner sceglie un indice per te. Tuttavia, se sai che un indice specifico funziona meglio, puoi utilizzare il suggerimento FORCE_INDEX
per scegliere di utilizzare l'indice vettoriale più appropriato per il tuo caso d'uso.
Per ulteriori informazioni, consulta la sezione Estratti conto VECTOR INDEX
.
Limitazioni
- Non puoi dividere in anticipo gli indici vettoriali. Per saperne di più, consulta la panoramica della pre-suddivisione.
Crea indice vettoriale
Per ottimizzare il recupero e il rendimento di un indice vettoriale, ti consigliamo di:
Crea l'indice vettoriale dopo che la maggior parte delle righe con gli incorporamenti è stata scritta nel database. Potresti anche dover ricreare periodicamente l'indice vettoriale dopo aver inserito nuovi dati. Per saperne di più, consulta la sezione Ricostruire l'indice vettoriale.
Utilizza la clausola
STORING
per archiviare una copia di una colonna nell'indice vettoriale. Se un valore di colonna è memorizzato nell'indice vettoriale, Spanner esegue il filtraggio a livello di foglia dell'indice per migliorare le prestazioni delle query. Ti consigliamo di memorizzare una colonna se viene utilizzata in una condizione di filtro. Per saperne di più sull'utilizzo diSTORING
in un indice, vedi Creare un indice per le scansioni solo indice.
Quando crei la tabella, la colonna di incorporamento deve essere un array di tipo di dati
FLOAT32
(consigliato) o FLOAT64
e deve avere un'annotazione vector_length,
che indica la dimensione dei vettori.
La seguente istruzione DDL crea una tabella Documents
con una colonna di incorporamento DocEmbedding
con una lunghezza del vettore:
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING (1024),
DocContents Bytes(MAX),
DocEmbedding ARRAY<FLOAT32>(vector_length=>128) NOT NULL,
NullableDocEmbedding ARRAY<FLOAT32>(vector_length=>128),
WordCount INT64,
) PRIMARY KEY (DocId);
Dopo aver compilato la tabella Documents
, puoi creare un indice vettoriale con una
struttura ad albero a due livelli e 1000 nodi foglia nella tabella Documents
con una colonna
di incorporamento DocEmbedding
utilizzando la distanza del coseno:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(DocEmbedding)
STORING (WordCount)
OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);
Se la colonna di incorporamento non è contrassegnata come NOT NULL
nella definizione della tabella, devi dichiararla con una clausola WHERE COLUMN_NAME IS NOT NULL
nella definizione dell'indice vettoriale, dove COLUMN_NAME
è il nome della colonna di incorporamento. Per
creare un indice vettoriale con un albero a tre livelli e 1.000.000 di nodi foglia nella
colonna di incorporamento Nullable NullableDocEmbedding
utilizzando la distanza coseno:
CREATE VECTOR INDEX DocEmbeddingThreeLevelIndex
ON Documents(NullableDocEmbedding)
STORING (WordCount)
WHERE NullableDocEmbedding IS NOT NULL
OPTIONS (distance_type = 'COSINE', tree_depth = 3, num_branches=1000, num_leaves = 1000000);
Filtrare un indice vettoriale
Puoi anche creare un indice vettoriale filtrato per trovare gli elementi più simili nel tuo database che corrispondono alla condizione di filtro. Un indice vettoriale filtrato indicizza selettivamente le righe che soddisfano le condizioni di filtro specificate, migliorando le prestazioni di ricerca.
Nel seguente esempio, la tabella Documents2
ha una colonna chiamata Category
.
Nella nostra ricerca vettoriale, vogliamo indicizzare la categoria "Tecnologia", quindi creiamo una
colonna generata che restituisce NULL
se la condizione della categoria non è soddisfatta.
CREATE TABLE Documents2 (
DocId INT64 NOT NULL,
Category STRING(MAX),
NullIfFiltered BOOL AS (IF(Category = 'Tech', TRUE, NULL)) HIDDEN,
DocEmbedding ARRAY<FLOAT32>(vector_length=>128),
) PRIMARY KEY (DocId);
Poi creiamo un indice vettoriale con un filtro. L'indice vettoriale TechDocEmbeddingIndex
indicizza solo i documenti della categoria "Tecnologia".
CREATE VECTOR INDEX TechDocEmbeddingIndex
ON Documents2(DocEmbedding)
STORING(NullIfFiltered)
WHERE DocEmbedding IS NOT NULL AND NullIfFiltered IS NOT NULL
OPTIONS (...);
Quando Spanner esegue la seguente query, che ha filtri che
corrispondono a TechDocEmbeddingIndex
, sceglie automaticamente ed è accelerata da
TechDocEmbeddingIndex
. La query cerca solo documenti nella categoria "Tecnologia". Puoi anche utilizzare {@FORCE_INDEX=TechDocEmbeddingIndex}
per forzare
Spanner a utilizzare TechDocEmbeddingIndex
in modo esplicito.
SELECT *
FROM Documents2
WHERE DocEmbedding IS NOT NULL AND NullIfFiltered IS NOT NULL
ORDER BY APPROX_(....)
LIMIT 10;
Passaggi successivi
Scopri di più sugli approssimativi vicini più prossimi di Spanner.
Scopri di più sulle funzioni GoogleSQL
APPROXIMATE_COSINE_DISTANCE()
,APPROXIMATE_EUCLIDEAN_DISTANCE()
,APPROXIMATE_DOT_PRODUCT()
.Scopri di più sulle istruzioni
VECTOR INDEX
GoogleSQL.Scopri di più sulle best practice per gli indici vettoriali.