Cercare e filtrare con gli embedding vettoriali

Questa pagina descrive i diversi modi in cui puoi eseguire query sugli incorporamenti vettoriali. Per una panoramica delle ricerche di similarità ANN e KNN, consulta Ricerche vettoriali.

Prima di iniziare

Abilita il flag di database cloudsql_vector sull'istanza Cloud SQL.

Per le istanze che utilizzano Cloud SQL per MySQL 9.7 o versioni successive, anche se non è necessario abilitare cloudsql_vector per creare e archiviare gli incorporamenti vettoriali, devi abilitare il flag di database cloudsql_vector sull'istanza Cloud SQL per creare indici vettoriali ed eseguire ricerche ANN sui dati vettoriali.

Cerca i vicini più prossimi approssimativi (ANN)

Per eseguire una ricerca ANN, utilizza la approx_distance funzione in una SELECT e ORDER BY clausola. Devi utilizzare una clausola LIMIT in una ricerca ANN. Puoi anche ottenere il valore della distanza inserendo approx_distance in un elenco SELECT.

Utilizza la seguente sintassi per le query ANN:

# Ordering by distance
SELECT title
FROM books
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
LIMIT 4;

# Selecting the distance value
SELECT
  approx_distance(
    embedding_name,
    string_to_vector('[1,2,3]'),
    'distance_measure=cosine,num_leaves_to_search=3')
    dist
FROM table
ORDER BY dist
LIMIT limit_value;

La funzione approx_distance utilizza le seguenti opzioni:

  • embedding: utilizza il nome della colonna di incorporamento vettoriale della tabella di base.
  • string_to_vector o vector_to_string: converte un vettore in una stringa e una stringa in un vettore per rendere il vettore leggibile.
  • distance_measure: specifica la misura della distanza da utilizzare per una ricerca di similarità vettoriale. Questo valore deve corrispondere al valore impostato nel parametro distance_measure quando hai creato l'indice. Questo parametro è obbligatorio. I valori possibili per questo parametro sono:
    • COSINE
    • L2_SQUARED
    • DOT_PRODUCT
  • num_leaves_to_search: facoltativo. Specifica il numero di nodi foglia da analizzare per una ricerca di similarità vettoriale ANN. Se non specifichi il numero di nodi foglia, Cloud SQL utilizza un valore generato in base alle dimensioni della tabella, al numero di nodi foglia nell'indice vettoriale e ad altri fattori. Puoi visualizzare questo valore in information_schema.innodb_vector_indexes. Ti consigliamo di ottimizzare num_leaves_to_search per ottenere il miglior equilibrio tra qualità e prestazioni di ricerca per il tuo workload specifico. Se aumentato, influisce sulle prestazioni, ma migliora il richiamo.

L'esempio seguente mostra come utilizzare approx_distance per trovare le K righe più vicine utilizzando la misura della distanza l2_squared e ordinare i risultati in base alla distanza.

# Ordering by distance
SELECT title
FROM books
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'),
                         'distance_measure=l2_squared')
LIMIT 4;

# Selecting the distance value
SELECT
    approx_distance
        (embedding, string_to_vector('[1,2,3]'),
         'distance_measure=l2_squared') dist
FROM table
ORDER BY dist
LIMIT 4;

Filtra i risultati delle query approx_distance

Puoi utilizzare la funzione approx_distance con le condizioni WHERE che filtrano i risultati delle query con un predicato non vettoriale per eseguire il post-filtraggio. La funzione approx_distance viene valutata prima dell'applicazione del filtro, il che significa che il numero di risultati restituiti è non deterministico.

Ad esempio, per la seguente query:

SELECT id FROM products WHERE price < 100
ORDER BY approx_distance(embedding, @query_vector,'distance_measure=cosine')
LIMIT 11;

La funzione approx_distance restituisce gli 11 vicini più prossimi al vettore di query, indipendentemente dal prezzo. Nel post-filtraggio, vengono selezionati i prodotti con un prezzo < 100. È possibile che tutti i vicini più prossimi abbiano un prezzo < 100, quindi la query restituisce 11 risultati. In alternativa, se nessuno dei vicini più prossimi ha un prezzo < 100, vengono restituite 0 righe.

Se prevedi che il filtro nella condizione WHERE sia molto selettivo, una ricerca esatta (KNN) è un'opzione per garantire che venga restituito un numero sufficiente di righe.

Un'altra opzione è utilizzare il filtraggio iterativo per analizzare una parte maggiore dell'indice di ricerca ANN.

Utilizza il filtraggio iterativo per aumentare i risultati di ricerca ANN

Puoi utilizzare il filtraggio iterativo quando i filtri selettivi della clausola WHERE nella query di ricerca ANN producono meno risultati rispetto al numero di risultati specificato nella clausola LIMIT.

Ad esempio, nella query seguente, quando abiliti il filtraggio iterativo, la query analizza una parte maggiore dell'indice vettoriale meno il primo set di risultati filtrati.

EXPLAIN FORMAT=TREE
SELECT * FROM t1 WHERE next_id BETWEEN 15 AND 100
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
LIMIT 10;

EXPLAIN
-> Limit: 10 row(s)  (rows=10)
   -> Vector index loop with iterative filtering
      -> Vector index scan on t1
      -> Filter: (t1.next_id between 15 and 100)
         -> Single-row index lookup on t1 using PRIMARY (id=t1.id)

Recuperi in modo iterativo più vicini dall'indice vettoriale di ricerca fino a raggiungere il massimo configurato (cloudsql_vector_iterative_filtering_max_neighbors). Tutte le corrispondenze dei filtri vengono conteggiate nel LIMIT e rimosse dalle scansioni aggiuntive dell'indice vettoriale.

Abilita il filtraggio iterativo

Per impostazione predefinita, il filtraggio iterativo è disattivato per tutte le sessioni e le istanze Cloud SQL.

Per abilitare il filtraggio iterativo per una sessione esistente, utilizza la seguente istruzione SQL.

SET SESSION cloudsql_vector_iterative_filtering=on;

Puoi anche abilitare il filtraggio iterativo a livello globale per tutte le sessioni client che si connettono all'istanza impostando il flag sull'istanza. Per impostare un flag per un'istanza, consulta Impostare un flag di database.

Per ulteriori informazioni sull'impostazione delle variabili di sistema a livello di sessione o globale, consulta Utilizzo delle variabili di sistema nella documentazione di MySQL.

Ottimizza il filtraggio iterativo

Per controllare il numero di vicini più prossimi restituiti per una query di ricerca ANN con il filtraggio iterativo abilitato, puoi utilizzare la variabile di sistema globale o di sessione cloudsql_vector_iterative_filtering_max_neighbors. Puoi utilizzare questa configurazione per aumentare il numero di vicini più prossimi richiesti. Tuttavia, per evitare di archiviare troppi risultati in memoria, il valore massimo per questa variabile è 1000.

Per impostare questa variabile per una sessione, utilizza la seguente istruzione SQL:

SET cloudsql_vector_iterative_filtering_max_neighbors=600;

Il valore predefinito è 500 e il numero minimo è 10.

Limitazioni

Di seguito sono riportate le limitazioni relative all'utilizzo del filtraggio iterativo:

  • Non è una garanzia: quando utilizzi il filtraggio iterativo, Cloud SQL tenta di trovare il numero di risultati specificato nella clausola LIMIT, ma non garantisce che il numero venga trovato. Questo può accadere se viene raggiunto il numero massimo di vicini (cloudsql_vector_iterative_filtering_max_neighbors) prima che il LIMIT sia soddisfatto o se non ci sono righe sufficienti che corrispondono al filtro nella tabella.

  • Query complesse: il filtraggio iterativo funziona solo quando i predicati di filtro vengono inseriti nel percorso di accesso della tabella di base. Non è supportato per i filtri sulle tabelle temporanee, ad esempio le tabelle che utilizzano una clausola HAVING. Nelle sottoquery, per il filtraggio iterativo vengono presi in considerazione solo i filtri sulla tabella di base all'interno della sottoquery stessa.

Controlla lo stato di fallback nelle ricerche ANN

In alcuni casi, una ricerca ANN esegue il fallback a una ricerca KNN. Questi includono i seguenti:

  • Non esiste un indice vettoriale nella tabella di base.
  • Esiste un indice vettoriale nella tabella di base, ma utilizza una misura della distanza diversa dal parametro distance_measure nelle opzioni di ricerca approx_distance.
  • L'indice vettoriale è danneggiato o invisibile alla transazione corrente.
  • Il LIMIT specificato è maggiore di 10000.
  • Non è specificato alcun LIMIT.
  • La query corrente include più di una chiamata approx_distance nella stessa tabella di base.
  • L'ottimizzatore calcola che è più efficiente utilizzare KNN.

In tutti questi casi, viene inviato un avviso al client che indica che è stata eseguita una ricerca esatta e il motivo.

Utilizza il seguente comando nel client mysql per visualizzare lo stato di fallback:

SHOW global status LIKE '%cloudsql_vector_knn_fallback%';

Se vuoi utilizzare ANN e viene eseguito il fallback a KNN, la query potrebbe essere più lenta. Devi trovare il motivo del fallback e valutare se apportare modifiche in modo che venga utilizzato ANN.

Esempio: crea un indice vettoriale ed esegui una query ANN

La seguente procedura dettagliata fornisce i passaggi per creare un indice vettoriale ed eseguire una query ANN in Cloud SQL.

  1. Genera gli incorporamenti vettoriali. Puoi creare gli incorporamenti vettoriali manualmente o utilizzare un'API di incorporamento di testo a tua scelta. Per un esempio che utilizza Vertex AI, consulta Generare incorporamenti vettoriali in base ai dati delle righe.
  2. Crea una tabella in Cloud SQL contenente una colonna di incorporamento vettoriale con tre dimensioni.

    CREATE TABLE books(
    id INTEGER PRIMARY KEY AUTO_INCREMENT, title VARCHAR(60), embedding VECTOR(3) USING VARBINARY);
    
  3. Inserisci un incorporamento vettoriale nella colonna.

    INSERT INTO books VALUES ((1, 'book title', string_to_vector('[1,2,3]')));
    
  4. Esegui il commit delle modifiche.

    commit;
    
  5. Crea l'indice vettoriale utilizzando la funzione L2_squared per misurare la distanza.

    CREATE
      VECTOR INDEX vectorIndex
    ON dbname.books(embeddings)
    USING SCANN QUANTIZER = SQ8 DISTANCE_MEASURE = l2_squared;
    
  6. Utilizza la seguente sintassi per eseguire una ricerca ANN con un LIMIT di 4 risultati di ricerca:

    SELECT title
    FROM books
    ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
    LIMIT 4;
    
    SELECT approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=cosine') dist
    FROM books
    ORDER BY dist
    LIMIT 4;
    

Cerca i vicini più prossimi (KNN)

Per eseguire una ricerca dei vicini più prossimi, utilizza la vector_distance funzione con un'opzione di misura della distanza e una funzione di conversione vettoriale (string_to_vector o vector_to_string) in un'istruzione SELECT. Utilizza la seguente sintassi:

SELECT vector_distance(string_to_vector('[1,2,3]'),
                      string_to_vector('[1,2,3]'),
                      'Distance_Measure=dot_product');

Sostituisci i valori [1,2,3] con i valori di incorporamento dei tuoi dati.

L'esempio seguente mostra come utilizzare questa query con la funzione cosine_distance e la funzione di conversione vettoriale string_to_vector.

SELECT id,cosine_distance(embedding, string_to_vector('[1,2,3]')) dist
FROM books
ORDER BY distance
LIMIT 10;

Ottieni la distanza del coseno in una query KNN

Utilizza la funzione cosine_distance di Cloud SQL per calcolare la distanza utilizzando il coseno.

SELECT cosine_distance(embedding, string_to_vector('[3,1,2]')) AS distance FROM books WHERE id = 10;

Ottieni la distanza del prodotto scalare in una query KNN

Utilizza la funzione dot_product di Cloud SQL per calcolare la distanza utilizzando il prodotto scalare.

SELECT dot_product(embedding, string_to_vector('[3,1,2]')) AS distance FROM books WHERE id = 10;

Ottieni la distanza al quadrato L2 in una query KNN

Utilizza la funzione l2_squared_distance di Cloud SQL per calcolare la distanza utilizzando L2 al quadrato.

SELECT
  l2_squared_distance(embedding, string_to_vector('[3,1,2]'))
    AS distance
FROM books
WHERE id = 10;

Passaggi successivi