Cercare e filtrare con gli embedding vettoriali

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

Cercare i vicini più prossimi approssimati (ANN)

Per eseguire una ricerca ANN, utilizza la funzione approx_distance in una clausola SELECT e ORDER BY. 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 vector embedding 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 a quello 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 foglie da analizzare per una ricerca di somiglianza vettoriale ANN. Se non specifichi il numero di foglie, Cloud SQL utilizza un valore generato in base alle dimensioni della tabella, al numero di foglie 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 della 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 prime K righe più vicine utilizzando la misura di 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;

Filtrare i risultati delle query approx_distance

Puoi utilizzare la funzione approx_distance con le condizioni WHERE che filtrano i risultati della 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 filtro post, 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 assicurarti che venga restituito un numero sufficiente di righe.

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

Utilizzare il filtraggio iterativo per aumentare i risultati di ricerca ANN

Puoi utilizzare il filtro 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 seguente query, quando attivi il filtro iterativo, la query esamina una parte maggiore dell'indice vettoriale meno il primo insieme 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 altri vicini dall'indice vettoriale di ricerca finché non viene raggiunto il massimo configurato (cloudsql_vector_iterative_filtering_max_neighbors). Tutte le corrispondenze dei filtri vengono conteggiate ai fini di LIMIT e rimosse dalle scansioni aggiuntive dell'indice vettoriale.

Attivare il filtro iterativo

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

Per attivare il filtro iterativo per una sessione esistente, utilizza la seguente istruzione SQL.

SET SESSION cloudsql_vector_iterative_filtering=on;

Puoi anche abilitare il filtro 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, vedi Impostare un flag di database.

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

Ottimizzare il filtro iterativo

Per controllare quanti vicini più prossimi vengono restituiti per una query di ricerca ANN con il filtro iterativo attivato, 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ù vicini richiesti. Tuttavia, per evitare di memorizzare troppi risultati, 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 filtro iterativo:

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

  • Query complesse: il filtro iterativo funziona solo quando i predicati del filtro vengono trasferiti al 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.

Controllare lo stato di fallback nelle ricerche ANN

In alcuni casi, una ricerca ANN viene eseguita come ricerca KNN. Questi includono:

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

In tutti questi casi, viene visualizzato un avviso per il cliente che indica che è stata eseguita la ricerca esatta e il motivo.

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

SHOW global status LIKE '%cloudsql_vector_knn_fallback%';

Se vuoi utilizzare ANN e viene eseguito il fallback a KNN, la query potrebbe essere eseguita più lentamente. Devi trovare il motivo per cui viene utilizzato il fallback e valutare se apportare modifiche in modo che venga utilizzata la rete neurale artificiale.

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 vector embedding. Puoi creare incorporamenti vettoriali manualmente o utilizzare un'API di incorporamento di testo a tua scelta. Per un esempio che utilizza Vertex AI, vedi Generare incorporamenti vettoriali in base ai dati delle righe.
  2. Crea una tabella in Cloud SQL contenente una colonna di vector embedding 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;
    

Ricerca K-Nearest Neighbor (KNN)

Per eseguire una ricerca K-Nearest Neighbor, utilizza la funzione vector_distance con un'opzione di misurazione della distanza e una funzione di conversione dei vettori (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.

Il seguente esempio mostra come utilizzare questa query con la funzione cosine_distance e la funzione di conversione dei vettori string_to_vector.

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

Ottenere la distanza coseno in una query KNN

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

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

Ottenere la distanza 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;

Ottenere la distanza al quadrato L2 in una query KNN

Utilizza la funzione Cloud SQL l2_squared_distance 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