Questa pagina descrive come utilizzare gli incorporamenti archiviati per generare indici ed eseguire query sugli incorporamenti utilizzando l'indice ScaNN
con AlloyDB per PostgreSQL.
Per saperne di più sull'archiviazione degli embedding, consulta
Archivia gli embedding vettoriali.
AlloyDB alloydb_scann
, un'estensione PostgreSQL sviluppata da Google che implementa un indice dei vicini più prossimi altamente efficiente basato sull'algoritmo ScaNN.
L'indice ScaNN
è un indice di quantizzazione basato su albero per la ricerca approssimativa
del vicino più prossimo. Offre tempi di creazione dell'indice più brevi e un utilizzo della memoria
inferiore rispetto a HNSW
. Inoltre, fornisce QPS più veloci rispetto a HNSW
in base al workload.
Prima di iniziare
Prima di poter iniziare a creare indici, devi completare i seguenti prerequisiti.
I vettori di incorporamento vengono aggiunti a una tabella nel tuo database AlloyDB.
Sono installate l'estensione
vector
basata supgvector
, estesa da Google per AlloyDB, e l'estensionealloydb_scann
:CREATE EXTENSION IF NOT EXISTS alloydb_scann CASCADE;
Se vuoi creare indici ScaNN ottimizzati automaticamente, assicurati che il flag
scann.enable_preview_features
sia attivato. Se non vuoi attivare le funzionalità di anteprima o per le istanze di produzione, puoi creare un indice ScaNN con parametri specifici.
Crea un indice ScaNN ottimizzato automaticamente
Con la funzionalità di indicizzazione automatica, puoi semplificare la creazione di indici per creare automaticamente indici ottimizzati per il rendimento della ricerca o tempi di creazione degli indici e rendimento della ricerca bilanciati.
Quando utilizzi la modalità AUTO
, devi specificare solo il nome della tabella e della colonna di incorporamento, nonché la funzione di distanza che vuoi utilizzare. Puoi ottimizzare l'indice per il rendimento della ricerca o trovare un equilibrio tra i tempi di creazione dell'indice e il rendimento della ricerca.
Esiste anche un'opzione per utilizzare la modalità MANUAL
per creare indici con un controllo granulare su altri parametri di ottimizzazione degli indici.
Crea un indice ScaNN in modalità AUTO
Ecco alcuni punti da tenere presenti prima di creare indici in modalità AUTO
:
- AlloyDB non può creare un indice ScaNN per tabelle con dati insufficienti.
- Non puoi impostare parametri di creazione dell'indice, ad esempio
num_leaves
, quando crei indici in modalitàAUTO
. - La manutenzione automatica è abilitata per impostazione predefinita per tutti gli indici creati in modalità
AUTO
.
Per creare un indice in modalità AUTO
, attiva prima il flag funzionalità scann.zero_knob_index_creation
.
Dopo aver abilitato il flag, esegui questo comando:
CREATE INDEX INDEX_NAME ON TABLE \
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) \
WITH (mode=AUTO', optimization='OPTIMIZATION');
Sostituisci quanto segue:
INDEX_NAME
: il nome dell'indice che vuoi creare, ad esempiomy-scann-index
. I nomi degli indici vengono 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
: la colonna che memorizza i dativector
.DISTANCE_FUNCTION
: la funzione di distanza da utilizzare con questo indice. Scegli una delle opzioni seguenti:Distanza L2:
l2
Prodotto scalare:
dot_product
Distanza coseno:
cosine
OPTIMIZATION
: impostato su uno dei seguenti valori:SEARCH_OPTIMIZED
: per ottimizzare sia il richiamo della ricerca vettoriale sia la latenza della ricerca vettoriale a costo di un tempo di creazione dell'indice più lungo.BALANCED
: per creare un indice che bilanci il tempo di creazione dell'indice e le prestazioni di ricerca.
Crea un indice ScaNN
in modalità MANUALE
Se hai attivato il flag scann.enable_preview_features
e vuoi un controllo granulare sui parametri di ottimizzazione, puoi creare l'indice in modalità MANUAL
.
Per creare un indice ScaNN
in modalità MANUAL
, esegui questo comando:
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=MAX_NUM_LEVELS]);
Sostituisci quanto segue:
INDEX_NAME
: il nome dell'indice che vuoi creare, ad esempiomy-scann-index
. I nomi degli indici vengono 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
: la colonna che memorizza i dativector
.DISTANCE_FUNCTION
: la funzione di distanza da utilizzare con questo indice. Scegli una delle opzioni seguenti:Distanza L2:
l2
Prodotto scalare:
dot_product
Distanza coseno:
cosine
NUM_LEAVES_VALUE
: il numero di partizioni da applicare a questo indice. Imposta un valore compreso tra 1 e 1048576.QUANTIZER
: il tipo di quantizzatore da utilizzare. Le opzioni disponibili sono le seguenti:SQ8
: offre un equilibrio tra il rendimento delle query e una perdita minima di recupero, in genere inferiore all'1-2%. Questo è il valore predefinito.AH
: prendi in considerazione questa opzione per un potenziale miglioramento delle prestazioni delle query quando il motore colonnare è attivato e i dati di indice e tabella vengono inseriti nel motore colonnare, in base alle dimensioni configurate. Tieni presente cheAH
è compresso fino a 4 volte rispetto aSQ8
. Per saperne di più, consulta Best practice per la regolazione di ScaNN.FLAT
: offre il richiamo più elevato, pari al 99% o superiore, a scapito delle prestazioni di ricerca.
MAX_NUM_LEVELS
: il numero massimo di livelli dell'albero del clustering K-means. Imposta su1
(valore predefinito) per la quantizzazione basata su albero a due livelli e su2
per la quantizzazione basata su albero a tre livelli.
Puoi aggiungere altri parametri di creazione dell'indice o di runtime della query per ottimizzare l'indice. Per saperne di più, consulta Ottimizzare un indice ScaNN
.
Modificare le modalità per gli indici esistenti
Se hai creato un indice ScaNN utilizzando la modalità AUTO
e vuoi ottimizzarlo manualmente, devi impostare la modalità su MANUAL
.
Per passare alla modalità MANUAL
, segui questi passaggi:
Aggiorna l'indice per impostare la modalità su
MANUAL
:ALTER INDEX INDEX_NAME SET (mode = 'MANUAL', num_leaves = NUM_LEAVES_VALUE);
Sostituisci quanto segue:
INDEX_NAME
: il nome dell'indice che vuoi creare, ad esempiomy-scann-index
. I nomi degli indici sono condivisi nel database. Verifica che ogni nome di indice sia univoco per ogni tabella del database.NUM_LEAVES_VALUE
: il numero di partizioni da applicare a questo indice. Imposta un valore compreso tra 1 e 1048576.
Puoi aggiungere altri parametri di creazione dell'indice o di runtime della query per ottimizzare l'indice. Per saperne di più, consulta Ottimizzare un indice
ScaNN
.Ricostruisci l'indice per applicare i parametri:
REINDEX INDEX CONCURRENTLY INDEX_NAME;
Per passare alla modalità AUTO
, completa i seguenti passaggi:
Aggiorna l'indice per impostare la modalità su
AUTO
:ALTER INDEX INDEX_NAME SET (mode = 'AUTO');
Ricostruisci l'indice per applicare i parametri:
REINDEX INDEX CONCURRENTLY INDEX_NAME;
Crea un indice ScaNN
con parametri specifici
Se la tua applicazione ha requisiti specifici per i tempi di richiamo e creazione dell'indice, puoi creare manualmente l'indice. Puoi creare un indice ad albero a due o tre livelli in base al tuo workload. Per ulteriori informazioni sull'ottimizzazione
dei parametri, consulta Ottimizzare un indice
ScaNN
.
Indice ad albero a due livelli
Per applicare un indice ad albero a due livelli utilizzando l'algoritmo ScaNN a una colonna contenente incorporamenti vettoriali archiviati, esegui la seguente query DDL:
CREATE INDEX INDEX_NAME ON TABLE
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
WITH (num_leaves=NUM_LEAVES_VALUE, quantizer =QUANTIZER);
Sostituisci quanto segue:
INDEX_NAME
: il nome dell'indice che vuoi creare, ad esempiomy-scann-index
. I nomi degli indici sono condivisi nel database. Assicurati che ogni nome di indice sia univoco per ogni tabella del database.TABLE
: la tabella a cui aggiungere l'indice.EMBEDDING_COLUMN
: una colonna che memorizza i dativector
.DISTANCE_FUNCTION
: la funzione di distanza da utilizzare con questo indice. Scegli una delle opzioni seguenti:Distanza L2:
l2
Prodotto scalare:
dot_product
Distanza coseno:
cosine
NUM_LEAVES_VALUE
: il numero di partizioni da applicare a questo indice. Imposta un valore compreso tra 1 e 1048576. Per ulteriori informazioni su come decidere questo valore, vedi Ottimizzare un indiceScaNN
.QUANTIZER
: il tipo di quantizzatore da utilizzare. Le opzioni disponibili sono le seguenti:SQ8
: offre un equilibrio tra il rendimento delle query e una perdita minima di recupero, in genere inferiore all'1-2%. Questo è il valore predefinito.AH
: prendi in considerazione questa opzione per un potenziale miglioramento delle prestazioni delle query quando il motore colonnare è attivato e i dati di indice e tabella vengono inseriti nel motore colonnare, in base alle dimensioni configurate. Tieni presente cheAH
è compresso fino a 4 volte rispetto aSQ8
. Per saperne di più, consulta Best practice per la regolazione di ScaNN.FLAT
: offre il richiamo più elevato, pari al 99% o superiore, a scapito delle prestazioni di ricerca.
Indice ad albero a tre livelli
Per creare un indice ad albero a tre livelli utilizzando l'algoritmo ScaNN in una colonna contenente incorporamenti vettoriali archiviati, esegui la seguente query DDL:
CREATE INDEX INDEX_NAME ON TABLE
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = 2);
Dopo aver creato l'indice, puoi eseguire query di ricerca del vicino più prossimo che utilizzano l'indice seguendo le istruzioni riportate in Eseguire una query del vicino più prossimo con un testo specifico.
I parametri dell'indice devono essere impostati in modo da trovare il giusto equilibrio tra QPS e
richiamo. Per saperne di più sull'ottimizzazione dell'indice ScaNN
, consulta Ottimizzare un indice ScaNN
.
Per creare questo indice in 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)
WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);
Sostituisci DIMENSIONS
con la larghezza dimensionale della
colonna di incorporamento. Per saperne di più su come trovare le dimensioni,
consulta la funzione vector_dims
in Funzioni
vettoriali.
Per ottenere un'esperienza di ricerca coerente, attiva la manutenzione automatica quando crei un indice ScaNN. Per saperne di più, consulta Gestire gli indici dei vettori. Questa funzionalità è disponibile in anteprima.
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.
Per ottimizzare l'indice per un equilibrio medio tra richiamo e QPS, consulta Ottimizzare un indice ScaNN
.
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.
La creazione dell'indice parallelo viene spesso attivata se crei un indice ScaNN a tre livelli o se il tuo set di dati supera i 100 milioni di righe.
Anche se AlloyDB ottimizza automaticamente il numero di worker paralleli, puoi ottimizzarli utilizzando i parametri di pianificazione delle query PostgreSQL max_parallel_maintenance_workers
, max_parallel_workers
e min_parallel_table_scan_size
.
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 un vettore di incorporamento, puoi eseguire la seguente query di esempio, in cui imposti la stessa funzione di distanza che hai utilizzato durante la creazione dell'indice.
SELECT * FROM TABLE
ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY ['EMBEDDING']
LIMIT ROW_COUNT
Sostituisci quanto segue:
TABLE
: la tabella contenente l'embedding a cui confrontare il testo.INDEX_NAME
: il nome dell'indice che vuoi utilizzare, ad esempiomy-scann-index
.EMBEDDING_COLUMN
: la colonna contenente gli incorporamenti archiviati.DISTANCE_FUNCTION_QUERY
: la funzione di distanza da utilizzare con questa query. Scegli una delle seguenti opzioni in base alla funzione di distanza utilizzata durante la creazione dell'indice:Distanza L2:
<->
Prodotto interno:
<#>
Distanza coseno:
<=>
EMBEDDING
: il vettore di embedding di cui vuoi trovare i vicini semantici memorizzati più vicini.ROW_COUNT
: il numero di righe da restituire.Specifica
1
se vuoi solo la corrispondenza migliore.
Puoi anche utilizzare la funzione embedding()
per tradurre il testo in un vettore. Poiché embedding()
restituisce un array real
, devi eseguire il cast esplicito della chiamata embedding()
a vector
prima di applicarla a uno degli operatori di ricerca dei vicini più prossimi (ad es. <->
per la distanza L2). Questi operatori possono quindi utilizzare l'indice ScaNN per trovare le righe del database con gli incorporamenti semanticamente più simili.
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.