Questa pagina descrive come creare un indice di vettori ed eseguire query sui vettori di embedding utilizzando la distanza di coseno approssimativa, la distanza euclidea approssimativa e le funzioni di vettore del prodotto scalare approssimativo. Puoi utilizzare queste funzioni per trovare vicini più prossimi approssimativi (ANN) in Spanner. Quando un set di dati è piccolo, puoi utilizzare la tecnica K-Nearest Neighbor (KNN) per trovare i vettori k-nearest esatti. Tuttavia, con l'aumento del set di dati, aumentano anche la latenza e il costo di una ricerca KNN. Puoi utilizzare le ANN per trovare i vicini più prossimi approssimativi con latenza e costi notevolmente ridotti.
K vicini più vicini approssimati
In una ricerca ANN, i vettori restituiti da k non sono i veri vicini più prossimi di k. A volte vengono restituiti alcuni vettori che non sono tra i k più vicini. Questo fenomeno è noto come perdita di richiamo. La quantità di perdita di richiamo accettabile dipende dal caso d'uso, ma nella maggior parte dei casi, perdere un po' di richiamo in cambio di un miglioramento delle prestazioni del database è un compromesso accettabile.
Per ulteriori dettagli sulle funzioni di distanza approssimativa di Spanner, consulta:
APPROX_COSINE_DISTANCE
in GoogleSQLAPPROX_EUCLIDEAN_DISTANCE
in GoogleSQLAPPROX_DOT_PRODUCT
in GoogleSQL
Indice vettoriale
Spanner accelera le ricerche di vettori ANN utilizzando un indice vettoriale specializzato. Questo indice si avvale dello strumento Scalable Nearest (Scalable Nearest)" di Google Research Vicino (ScaNN), un algoritmo molto efficiente per il vicino più prossimo.
L'indice di vettori utilizza una struttura basata su albero per partizionare i dati e favorire ricerche più rapide. Spanner offre configurazioni ad albero sia a due che a tre livelli:
- Configurazione ad albero a due livelli: i nodi foglia (
num_leaves
) contengono gruppi di vettori strettamente correlati insieme al centroide corrispondente. Il livello radice è costituito dai centroidi di tutti i nodi foglia. - Configurazione ad albero su tre livelli: concettualmente simile a un albero a due livelli, mentre
introducendo un ulteriore strato di ramo (
num_branches
), da cui nodo foglia i centroidi sono ulteriormente partizionati in modo da formare il livello principale (num_leaves
).
Inoltre, devi creare l'indice di vettori con una metrica di distanza specifica.
Puoi scegliere la metrica di distanza più appropriata per il tuo caso d'uso impostando
distance_type
a uno tra COSINE
, DOT_PRODUCT
o EUCLIDEAN
.
Per saperne di più, consulta gli estratto conto di VECTOR INDEX
.
Limitazioni
L'indice vettoriale di Spanner ha le seguenti limitazioni:
ALTER VECTOR INDEX
non supportato.
Crea indice vettoriale
Per ottimizzare al meglio l'indice vettoriale per un buon richiamo e prestazioni, consigliamo di creare l'indice vettoriale dopo che la maggior parte delle righe con incorporamenti sono vengono scritte nel database. Potrebbe essere necessario inoltre eseguire periodicamente ricreare l'indice vettoriale dopo aver inserito nuovi dati. Per ulteriori informazioni, vedi Ricrea l'indice vettoriale.
Per creare un indice vettoriale con un albero a due livelli e 1000 nodi foglia su una
Tabella Documents
con una colonna di incorporamento DocEmbedding
che utilizza il coseno
distanza:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(DocEmbedding)
OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);
Per creare un indice vettoriale con un albero a tre livelli e 1000000 nodi foglia:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(NullableDocEmbedding)
WHERE NullableDocEmbedding IS NOT NULL
OPTIONS (distance_type = 'COSINE', tree_depth = 3, num_branches=1000, num_leaves = 1000000);
Se la colonna di incorporamento è nullable, devi dichiararla con una clausola WHERE column_name IS NOT NULL
:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(NullableDocEmbedding)
WHERE NullableDocEmbedding IS NOT NULL
OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);
Esegui query sugli embedding vettoriali
Per eseguire una query su un indice di vettori, utilizza una delle tre funzioni di distanza approssimativa:
APPROX_COSINE_DISTANCE
APPROX_EUCLIDEAN_DISTANCE
APPROX_DOT_PRODUCT
Le limitazioni relative all'utilizzo delle funzioni di distanza approssimativa includono seguenti:
- Per utilizzare l'indice vettoriale, devi fornire un suggerimento per la query.
- Devi utilizzare un'espressione costante come argomento della funzione di distanza (ad esempio un parametro o un valore letterale).
- La query o la sottoquery in cui viene utilizzata la funzione di distanza approssimativa deve
hanno una forma specifica: la funzione di distanza deve essere l'unico tasto
ORDER BY
, ed è necessario specificare un limite.
Per un elenco dettagliato delle limitazioni, consulta la pagina di riferimento della funzione di distanza approssimativa.
Esempio
Per cercare i 100 vettori più vicini a [1.0, 2.0, 3.0]
:
SELECT DocId
FROM Documents@{FORCE_INDEX=DocEmbeddingIndex}
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
Se la colonna di incorporamento ammette valori nulli:
SELECT DocId
FROM Documents@{FORCE_INDEX=DocEmbeddingIndex}
WHERE NullableDocEmbedding IS NOT NULL
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
Best practice
Segui queste best practice per ottimizzare i tuoi indici vettoriali e migliorare le query che consentono di analizzare i dati e visualizzare i risultati.
Ottimizza le opzioni di ricerca vettoriale
Il valore di ricerca vettoriale ottimale dipende dal caso d'uso, il vettore e sui vettori di query. Potresti dover eseguire un'ottimizzazione iterativa i valori migliori per il tuo carico di lavoro specifico.
Ecco alcune linee guida utili da seguire per scegliere valori appropriati:
tree_depth
(a livello di albero): se la tabella da indicizzare ha meno di 10 milioni di righe, utilizza un valoretree_depth
di2
. In caso contrario, un valore ditree_depth
di3
supporta tabelle con un massimo di 10 miliardi di righe.num_leaves
: utilizza la radice quadrata del numero di righe nel set di dati. Un valore più elevato può aumentare il tempo di compilazione dell'indice di vettori. Evita di impostarenum_leaves
più grande ditable_row_count/1000
, perché le foglie sono troppo piccole e un rendimento scarso.num_leaves_to_search
: questa opzione specifica il numero di nodi fogli dell'indice sottoposti a ricerca. L'aumento dinum_leaves_to_search
migliora il richiamo, ma aumenta anche la latenza e i costi. Ti consigliamo di utilizzare un numero che corrisponda all'1% del totale numero di foglie definito nell'istruzioneCREATE VECTOR INDEX
come valore pernum_leaves_to_search
. Se utilizzi una clausola di filtro, aumenta questo valore per ampliare la ricerca.
Se si ottiene un richiamo accettabile, ma il costo dell'interrogazione è troppo elevato,
generando un valore QPS massimo basso, prova ad aumentare num_leaves
seguendo questi
passaggi:
- Imposta
num_leaves
su alcuni multipli k del suo valore originale (ad esempio,2 * sqrt(table_row_count)
). - Imposta
num_leaves_to_search
come lo stesso multiplo k del valore originale. - Prova a ridurre
num_leaves_to_search
per migliorare il costo e il QPS mantenendo il richiamo.
Migliorare il ricordo
Esistono diverse possibilità di peggioramento del richiamo, tra cui:
num_leaves_to_search
è troppo piccolo: potresti riscontrare difficoltà a trovare i vicini più prossimi per alcuni vettori di query, quindi aumentarenum_leaves_to_search
per cercare più foglie può contribuire a migliorare il richiamo. Le query recenti potrebbero aver iniziato a contenere più di questi vettori difficili.L'indice di vettori deve essere ricostruito: la struttura ad albero dell'indice di vettori è ottimizzata per il set di dati al momento della creazione ed è statica in seguito. Pertanto, se vengono aggiunti vettori notevolmente diversi dopo la creazione dell'indice iniziale dei vettori, la struttura ad albero potrebbe non essere ottimale, con un conseguente peggioramento del recupero.
Ricrea l'indice vettoriale
Per ricreare l'indice vettoriale senza tempi di inattività:
- Crea un nuovo indice vettoriale nella stessa colonna di incorporamento del vettore corrente
di Google, aggiornando i parametri (ad es.
OPTIONS
) in modo appropriato. - Al termine della creazione dell'indice, modifica il suggerimento
FORCE_INDEX
puntare al nuovo indice per aggiornare la query di ricerca vettoriale. In questo modo, la query utilizzerà il nuovo indice di vettori. Potresti anche dover eseguire nuovamente l'accordaturanum_leaves_to_search
nella nuova query. - Elimina l'indice vettoriale obsoleto.
Passaggi successivi
Scopri di più sulle funzioni GoogleSQL
APPROXIMATE_COSINE_DISTANCE()
,APPROXIMATE_EUCLIDEAN_DISTANCE()
eAPPROXIMATE_DOT_PRODUCT()
.Scopri di più sulle istruzioni
VECTOR INDEX
di GoogleSQL.