Utilizza gli incorporamenti archiviati per generare indici vettoriali ScaNN ed eseguire query sugli incorporamenti con AlloyDB per PostgreSQL.
L'indice ScaNN è un indice di quantizzazione basato su alberi creato da Google per la ricerca del vicino più prossimo approssimato. Offre tempi di creazione dell'indice più brevi e un footprint della memoria più piccolo rispetto a HNSW. Inoltre, offre QPS più veloci rispetto a HNSW in base al carico di lavoro.
Prima di iniziare
Prima di poter iniziare a creare indici, devi completare i seguenti prerequisiti.
I vettori di embedding vengono aggiunti a una tabella nel tuo database AlloyDB.
Se provi a generare un indice ScaNN su una tabella vuota o partizionata, potresti riscontrare alcuni problemi. Per saperne di più sugli errori generati, consulta Risolvere i problemi relativi agli errori dell'indice ScaNN. Per creare un indice in una tabella vuota o di piccole dimensioni, vedi Creazione differita dell'indice per tabelle vuote o quasi vuote.
Sono installate le estensioni
vectorealloydb_scann:CREATE EXTENSION IF NOT EXISTS alloydb_scann CASCADE;L'installazione dell'estensione
alloydb_scannverifica automaticamente se l'estensionevectorè installata e la installa in caso contrario. Non devi installare manualmentevectorseparatamente.Se vuoi creare un indice ScaNN a quattro livelli, devi prima attivare la funzionalità Anteprima per la tua istanza AlloyDB. Per attivare la funzionalità Anteprima, scegli uno dei seguenti due metodi:
Attiva il flag di database
scann.enable_preview_features.Per saperne di più sulla configurazione dei flag di database, vedi Configurare i flag di database.
Imposta il flag di database
scann.max_allowed_num_levelssu3a livello di sessione o istanza. Per impostare il flag a livello di sessione, esegui questo comando:SET scann.max_allowed_num_levels = 3;Per impostare il flag a livello di istanza, esegui
gcloud alloydb alloydb instances updateutilizzando il campo--database-flags.
Creare un indice ottimizzato automaticamente
Gli indici ScaNN ottimizzati automaticamente semplificano la creazione degli indici consentendo ad AlloyDB di gestire e ottimizzare la struttura dell'indice. Se hai bisogno di un controllo granulare della regolazione dell'indice, crea un indice ScaNN regolato manualmente.
Gli indici ottimizzati automaticamente possono essere ottimizzati in due modi:
- (Predefinito) Recupero e latenza della ricerca vettoriale a scapito del tempo di compilazione dell'indice
- Bilanciare il tempo di compilazione dell'indice e il rendimento della ricerca
Per creare un indice ScaNN ottimizzato automaticamente, esegui questo comando.
CREATE INDEX INDEX_NAME ON TABLE
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
Sostituisci quanto segue:
INDEX_NAME: il nome dell'indice che vuoi creare. Ad esempio,my_scann_index. I nomi degli indici sono condivisi nel database. Verifica che ogni nome di indice sia univoco per ogni tabella del database.TABLE: la tabella a cui aggiungere l'indice.EMBEDDING_COLUMN: colonna che memorizza i dativector.DISTANCE_FUNCTION: funzione di distanza da utilizzare con questo indice. Scegli una delle opzioni seguenti:Distanza L2:
l2Prodotto scalare:
dot_productDistanza coseno:
cosine
Questo comando crea un indice ScaNN ottimizzato per il rendimento della ricerca ed esegue la manutenzione automatica dell'indice. Se vuoi modificare una di queste impostazioni, esegui il seguente comando:
CREATE INDEX INDEX_NAME ON TABLE
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
WITH (MODE='AUTO',
OPTIMIZATION='OPTIMIZATION',
auto_maintenance='AUTO_MAINTENANCE')
Sostituisci quanto segue:
INDEX_NAME: il nome dell'indice che vuoi creare. Ad esempio,my_scann_index. I nomi degli indici sono condivisi nel database. Verifica che ogni nome di indice sia univoco per ogni tabella del database.TABLE: la tabella a cui aggiungere l'indice.EMBEDDING_COLUMN: colonna che memorizza i dativector.DISTANCE_FUNCTION: funzione di distanza da utilizzare con questo indice. Scegli una delle opzioni seguenti:Distanza L2:
l2Prodotto scalare:
dot_productDistanza coseno:
cosine
(Facoltativo)
OPTIMIZATION: imposta uno dei seguenti valori:(Predefinito)
SEARCH_OPTIMIZED: ottimizza sia il richiamo della ricerca vettoriale sia la latenza della ricerca vettoriale a costo di tempi di creazione dell'indice più lunghi.BALANCED: bilancia il tempo di compilazione dell'indice e le prestazioni di ricerca.
Se
OPTIMIZATIONè impostato, deve essere incluso ancheMODE='AUTO'.(Facoltativo)
AUTO_MAINTENANCE: controlla se la manutenzione automatica dell'indice è attivata o disattivata. Per saperne di più sulla manutenzione automatica, consulta Mantenere gli indici vettoriali.(Predefinito)
ON: AlloyDB esegue la manutenzione automatica dell'indice.OFF: AlloyDB non esegue la manutenzione automatica dell'indice.
Creare un indice ottimizzato manualmente
Se la tua applicazione ha requisiti specifici per i tempi di richiamo e creazione dell'indice, puoi creare e ottimizzare manualmente l'indice ScaNN.
Per creare manualmente un indice ScaNN per una colonna contenente incorporamenti di vettori memorizzati, consulta i seguenti comandi.
Indice ad albero a due livelli
CREATE INDEX INDEX_NAME ON TABLE USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) WITH (mode='MANUAL', num_leaves=NUM_LEAVES_VALUE, quantizer=QUANTIZER, auto_maintenance=AUTO_MAINTENANCE);
-
INDEX_NAME: il nome dell'indice che vuoi creare. Ad esempio,my_scann_index. I nomi degli indici vengono condivisi nel tuo database. Assicurati che ogni nome di indice sia univoco per ogni tabella del tuo database. -
TABLE: la tabella a cui aggiungere l'indice. -
EMBEDDING_COLUMN: colonna che memorizza i dati `vector`. -
DISTANCE_FUNCTION: funzione di distanza da utilizzare con questo indice. Scegli una delle seguenti opzioni:- Distanza L2:
l2 - Prodotto scalare:
dot_product - Distanza coseno:
cosine
- Distanza L2:
-
NUM_LEAVES_VALUE: numero di partizioni da applicare a questo indice. Imposta un valore compreso tra 1 e 30 milioni. Per ulteriori informazioni su come scegliere questo valore, vedi Ottimizzare un indiceScaNN. -
QUANTIZER: tipo di quantizzatore da utilizzare. Tieni presente che l'indice ScaNN può essere caricato nel motore colonnare per accelerare ulteriormente la ricerca vettoriale. Scegli una delle seguenti opzioni:-
(Predefinito)
SQ8: offre un equilibrio tra le prestazioni delle query con una perdita minima di richiamo. In genere, questa percentuale è inferiore all'1-2%. -
Anteprima
AH: l'hashing asimmetrico (AH) è fino a 4 volte più compresso rispetto aSQ8. Per un potenziale miglioramento delle prestazioni delle query quando il motore colonnare è abilitato e i dati di indice e tabella vengono inseriti nel motore colonnare, prendi in considerazione questa opzione per un potenziale miglioramento delle prestazioni delle query. Per saperne di più, consulta le best practice per l'ottimizzazione di ScaNN. -
FLAT: fornisce il richiamo più elevato, pari al 99% o superiore, a scapito delle prestazioni di ricerca.
-
(Predefinito)
-
(Facoltativo)
AUTO_MAINTENANCE: controlla se la manutenzione automatica dell'indice è attivata o disattivata. Per saperne di più sulla manutenzione automatica, consulta Gestire gli indici vettoriali.-
(Predefinito)
ON: AlloyDB esegue la manutenzione automatica dell'indice. -
OFF: AlloyDB non esegue la manutenzione automatica dell'indice.
-
(Predefinito)
Indice ad albero a tre livelli
CREATE INDEX INDEX_NAME ON TABLE USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) WITH (mode='MANUAL', num_leaves=NUM_LEAVES_VALUE, quantizer=QUANTIZER, auto_maintenance=AUTO_MAINTENANCE, max_num_levels = 2);
-
INDEX_NAME: il nome dell'indice che vuoi creare. Ad esempio,my_scann_index. I nomi degli indici vengono condivisi nel tuo database. Assicurati che ogni nome di indice sia univoco per ogni tabella del tuo database. -
TABLE: la tabella a cui aggiungere l'indice. -
EMBEDDING_COLUMN: colonna che memorizza i dati `vector`. -
DISTANCE_FUNCTION: funzione di distanza da utilizzare con questo indice. Scegli una delle seguenti opzioni:- Distanza L2:
l2 - Prodotto scalare:
dot_product - Distanza coseno:
cosine
- Distanza L2:
-
NUM_LEAVES_VALUE: numero di partizioni da applicare a questo indice. Imposta un valore compreso tra 1 e 30 milioni. Per ulteriori informazioni su come scegliere questo valore, vedi Ottimizzare un indiceScaNN. -
QUANTIZER: tipo di quantizzatore da utilizzare. Tieni presente che l'indice ScaNN può essere caricato nel motore colonnare per accelerare ulteriormente la ricerca vettoriale. Scegli una delle seguenti opzioni:-
(Predefinito)
SQ8: offre un equilibrio tra le prestazioni delle query con una perdita minima di richiamo. In genere, questa percentuale è inferiore all'1-2%. -
Anteprima
AH: l'hashing asimmetrico (AH) è fino a 4 volte più compresso rispetto aSQ8. Per un potenziale miglioramento delle prestazioni delle query quando il motore colonnare è abilitato e i dati di indice e tabella vengono inseriti nel motore colonnare, prendi in considerazione questa opzione per un potenziale miglioramento delle prestazioni delle query. Per saperne di più, consulta le best practice per l'ottimizzazione di ScaNN. -
FLAT: fornisce il richiamo più elevato, pari al 99% o superiore, a scapito delle prestazioni di ricerca.
-
(Predefinito)
-
(Facoltativo)
AUTO_MAINTENANCE: controlla se la manutenzione automatica dell'indice è attivata o disattivata. Per saperne di più sulla manutenzione automatica, consulta Gestire gli indici vettoriali.-
(Predefinito)
ON: AlloyDB esegue la manutenzione automatica dell'indice. -
OFF: AlloyDB non esegue la manutenzione automatica dell'indice.
-
(Predefinito)
Indice ad albero a quattro livelli
Gli indici ad albero a quattro livelli sono in anteprima.
CREATE INDEX INDEX_NAME ON TABLE USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) WITH (mode='MANUAL', num_leaves=NUM_LEAVES_VALUE, quantizer=QUANTIZER, max_num_levels = 3);
-
INDEX_NAME: il nome dell'indice che vuoi creare. Ad esempio,my_scann_index. I nomi degli indici vengono condivisi nel tuo database. Assicurati che ogni nome di indice sia univoco per ogni tabella del tuo database. -
TABLE: la tabella a cui aggiungere l'indice. -
EMBEDDING_COLUMN: colonna che memorizza i dati `vector`. -
DISTANCE_FUNCTION: funzione di distanza da utilizzare con questo indice. Scegli una delle seguenti opzioni:- Distanza L2:
l2 - Prodotto scalare:
dot_product - Distanza coseno:
cosine
- Distanza L2:
-
NUM_LEAVES_VALUE: numero di partizioni da applicare a questo indice. Imposta un valore compreso tra 1 e 30 milioni. Per ulteriori informazioni su come scegliere questo valore, vedi Ottimizzare un indiceScaNN. -
QUANTIZER: tipo di quantizzatore da utilizzare. Tieni presente che l'indice ScaNN può essere caricato nel motore colonnare per accelerare ulteriormente la ricerca vettoriale. Scegli una delle seguenti opzioni:-
(Predefinito)
SQ8: offre un equilibrio tra le prestazioni delle query con una perdita minima di richiamo. In genere, questa percentuale è inferiore all'1-2%. -
Anteprima
AH: l'hashing asimmetrico (AH) è fino a 4 volte più compresso rispetto aSQ8. Per un potenziale miglioramento delle prestazioni delle query quando il motore colonnare è abilitato e i dati di indice e tabella vengono inseriti nel motore colonnare, prendi in considerazione questa opzione per un potenziale miglioramento delle prestazioni delle query. Per saperne di più, consulta le best practice per l'ottimizzazione di ScaNN. -
FLAT: fornisce il richiamo più elevato, pari al 99% o superiore, a scapito delle prestazioni di ricerca.
-
(Predefinito)
Convertire un indice ottimizzato manualmente in un indice ottimizzato automaticamente
Per convertire un indice ottimizzato manualmente in un indice ottimizzato automaticamente, completa i seguenti passaggi:
Reimposta tutti parametri di ricerca definiti per l'indice ottimizzato manualmente.
ALTER INDEX INDEX_NAME RESET (PARAMETER_NAME);Sostituisci le seguenti variabili:
INDEX_NAME: il nome dell'indice che vuoi convertire. Ad esempio,my_scann_index. I nomi degli indici sono condivisi nel database. Verifica che ogni nome di indice sia univoco per ogni tabella del database.PARAMETER_NAME: un elenco separato da virgole contenente i nomi dei parametri di ricerca che vuoi reimpostare. Ad esempio,num_leaves, quantization.Tieni presente che devi reimpostare tutti gli altri parametri di ricerca prima di reimpostare
num_leaves.
Reindicizza l'indice ottimizzato manualmente per convertirlo in un indice ottimizzato automaticamente.
REINDEX INDEX CONCURRENTLY INDEX_NAME;
Crea un indice ScaNN per i tipi di dati real[]
Per creare un indice per una colonna di incorporamento che utilizza il tipo di dati real[] anziché vector, esegui il cast della colonna nel tipo di dati vector:
CREATE INDEX INDEX_NAME ON TABLE
USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)
Sostituisci quanto segue:
INDEX_NAME: il nome dell'indice che vuoi creare. Ad esempio,my_scann_index. I nomi degli indici sono condivisi nel database. Verifica che ogni nome di indice sia univoco per ogni tabella del database.TABLE: la tabella a cui aggiungere l'indice.EMBEDDING_COLUMN: colonna che memorizza i dativector.DISTANCE_FUNCTION: funzione di distanza da utilizzare con questo indice. Scegli una delle opzioni seguenti:Distanza L2:
l2Prodotto scalare:
dot_productDistanza coseno:
cosine
Visualizzare l'avanzamento dell'indicizzazione
Per visualizzare l'avanzamento dell'indicizzazione, utilizza la visualizzazione pg_stat_progress_create_index:
SELECT * FROM pg_stat_progress_create_index;
La colonna phase mostra lo stato attuale della creazione dell'indice. Una volta completata la fase di creazione dell'indice, la riga dell'indice non è visibile.
Crea un indice differito per tabelle vuote o con un numero insufficiente di righe
Per impostazione predefinita, non puoi creare un indice ScaNN su una tabella vuota o con un numero di righe inferiore al valore dell'opzione di indice num_leaves.
Per aggirare questa limitazione, attiva la creazione differita dell'indice per consentire
ad AlloyDB di posticipare la creazione dell'indice fino a quando il numero di righe nella
tabella non raggiunge la soglia definita da num_leaves. Una volta raggiunto
il limite, AlloyDB avvia la creazione dell'indice in background.
Questa operazione differita è un processo non bloccante, che consente ad altre operazioni del database, come letture e scritture, di continuare senza interruzioni. Poiché la ricompilazione dell'indice avviene in background, la creazione differita dell'indice è adatta quando le tabelle inseriscono righe di dati in piccoli batch. La ricompilazione dell'indice viene attivata automaticamente quando il numero di righe raggiunge la soglia.
Tuttavia, se prevedi di inserire un numero elevato di righe nella tabella in una singola transazione, ti consigliamo di dividere la transazione in più transazioni o di generare un indice ScaNN senza attivare la creazione differita dell'indice.
Abilita la creazione di indici posticipata
Per attivare la creazione differita dell'indice:
Attiva il flag
scann.enable_index_maintenance(attivo per impostazione predefinita) e il flagscann.enable_preview_features. Il flagscann.enable_preview_featuresattiva anche altre funzionalità di anteprima.gcloud alloydb instances update INSTANCE_ID \ --database-flags scann.enable_index_maintenance=on \ --database-flags scann.enable_preview_features=on \ --region=REGION_ID \ --cluster=CLUSTER_ID \ --project=PROJECT_IDSostituisci quanto segue:
INSTANCE_ID: l'ID dell'istanza.REGION_ID: la regione in cui si trova l'istanza, ad esempious-central1.CLUSTER_ID: l'ID del cluster in cui si trova l'istanza.PROJECT_ID: l'ID del progetto in cui si trova il cluster.
Crea un indice ScaNN. Se crei un indice in modalità manuale, assicurati che il parametro
auto_maintenancesia impostato suon. Per saperne di più, consulta Creare un indice ottimizzato manualmente.
Limitazioni
- Il processo in background di creazione automatica dell'indice utilizza i valori dei flag a livello di database. Anche se imposti flag a livello di sessione utilizzando il comando
SET LOCAL, il processo considera il valore del flag impostato a livello di database. - Se prevedi di inserire collettivamente una grande quantità di dati in una tabella vuota in una singola transazione, ti consigliamo di eseguire la singola transazione di inserimento e poi creare un indice ScaNN.
Forzare la creazione dell'indice su tabelle vuote o piccole
AlloyDB utilizza le convalide per impedire la creazione di un indice ScaNN su una tabella vuota o con pochissime righe per i seguenti motivi:
L'indice ScaNN viene addestrato su dati insufficienti. Ciò può comportare un richiamo scarso per le ricerche di similarità vettoriale.
Le prestazioni di scrittura nel database potrebbero peggiorare.
Ti consigliamo di posticipare la creazione dell'indice per evitare prestazioni non ottimali.
Tuttavia, in alcuni scenari di sviluppo o test, potrebbe essere necessario creare un indice su una tabella vuota o di piccole dimensioni. In questi casi, puoi forzare la creazione
dell'indice. Tieni presente che l'applicazione forzata della creazione dell'indice richiede privilegi SUPERUSER.
Per forzare la creazione dell'indice, completa i seguenti passaggi:
Imposta il parametro a livello di sessione
scann.allow_blocked_operations creationsutruenel database:SET scann.allow_blocked_operations = true;Se l'utente che utilizzi per eseguire queste query non dispone dei privilegi
SUPERUSER, assegnali:CREATE USER USERNAME WITH SUPERUSER PASSWORD PASSWORD;Sostituisci le seguenti variabili:
USERNAME: il nome dell'utente a cui vuoi concedere i privilegiSUPERUSER.PASSWORD: la password dell'utente.
Crea indici in parallelo
Per creare l'indice più rapidamente, AlloyDB potrebbe generare automaticamente più worker paralleli a seconda del set di dati e del tipo di indice scelto. Questo si verifica spesso quando crei un indice ScaNN a tre o quattro livelli o se il set di dati supera i 100 milioni di righe.
Sebbene AlloyDB ottimizzi automaticamente il numero di worker paralleli, puoi ottimizzarli utilizzando i seguenti parametri di pianificazione delle query PostgreSQL:
Per evitare problemi di memoria insufficiente durante la creazione dell'indice ScaNN, assicurati che i flag di database
maintenance_work_mem
e
shared_buffers
siano impostati su un valore inferiore alla memoria totale della macchina.
Esegui una query
Dopo aver archiviato e indicizzato gli incorporamenti nel database, puoi iniziare
a eseguire query sui dati. Non puoi eseguire query di ricerca collettive utilizzando l'estensione alloydb_scann.
Per trovare i vicini semantici più vicini per una stringa di testo, puoi utilizzare la funzione
google_ml.embedding() per tradurre il testo in un vettore.
Poiché google_ml.embedding() restituisce un array reale, devi eseguire il cast esplicito
della chiamata di funzione a vector prima di applicarla a uno degli operatori
di ricerca dei vicini più prossimi, ad esempio <-> per la distanza L2. Questi operatori possono quindi utilizzare l'indice ScaNN per trovare le righe del database con gli incorporamenti semanticamente più simili.
SELECT * FROM TABLE
ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY
google_ml.embedding(
model_id => 'MODEL_ID',
content => 'CONTENT')::vector
LIMIT ROW_COUNT
Sostituisci le seguenti variabili:
TABLE: tabella contenente l'embedding a cui confrontare il testo.INDEX_NAME: il nome dell'indice che vuoi utilizzare. Ad esempio,my_scann_index.EMBEDDING_COLUMN: colonna contenente gli embedding archiviati.DISTANCE_FUNCTION_QUERY: funzione di distanza da utilizzare con questa query. Scegli l'equivalente della query per la funzione di distanza quando hai creato l'indice:Distanza L2:
<->Prodotto interno:
<#>Distanza coseno:
<=>
MODEL_ID: l'ID del modello di incorporamento registrato che vuoi utilizzare.CONTENT: la stringa di testo che vuoi tradurre in un embedding e cercare.ROW_COUNT: numero di righe da restituire. Ad esempio, specifica1se vuoi la corrispondenza singola migliore.
Passaggi successivi
- Esegui ricerche di similarità vettoriale
- Ottimizzare il rendimento delle query vettoriali
- Metriche dell'indice vettoriale
- Scopri come creare un assistente per lo shopping intelligente con AlloyDB, pgvector e la gestione degli endpoint del modello.