Best practice per la ricerca vettoriale

Questo documento fornisce consigli per ottimizzare il rendimento della ricerca vettoriale in Spanner.

Comprendere le nozioni di base di Spanner

Per eseguire test di rendimento efficaci della ricerca vettoriale di Spanner, devi comprendere le nozioni di base di Spanner. Ad esempio, la riesecuzione immediata della stessa query può essere più veloce grazie alle cache. Per testare il rendimento di un'applicazione che utilizza principalmente dati attivi, esegui prima una lettura di riscaldamento.

Consulta le seguenti guide:

Spanner elabora le query in parallelo in base alle suddivisioni del database. Il test con un carico di query di produzione sostenuto può consentire la suddivisione basata sul carico, che migliora il rendimento delle query grazie a un maggiore parallelismo. Per aumentare il parallelismo per il carico futuro, valuta la possibilità di pre-suddividere il database, soprattutto per KNN.

Best practice per la ricerca vettoriale

Questo documento descrive le seguenti best practice per la ricerca vettoriale:

Annotare la colonna di embedding

Annota la colonna di embedding con vector_length. Questa annotazione consente le ottimizzazioni del rendimento per la ricerca K-Nearest Neighbor (KNN) ed è un prerequisito per la ricerca Approximate Nearest Neighbor (ANN).

Utilizzare una query top-k

Per trovare i vicini più prossimi, utilizza una clausola ORDER BY con LIMIT. Le query top-k sono altamente ottimizzate per la ricerca vettoriale. Evita di filtrare in base a una soglia di distanza in una clausola WHERE.

Ad esempio, la seguente non è consigliata:

SELECT d.DocId
FROM Documents AS d
WHERE COSINE_DISTANCE(d.DocEmbedding, @vector) < 1;

Utilizza invece:

SELECT d.DocId
FROM Documents AS d
ORDER BY COSINE_DISTANCE(d.DocEmbedding, @vector)
LIMIT 10;

L'utilizzo di una query top-k non è solo più semplice perché elimina la regolazione della soglia di distanza, ma consente anche ottimizzazioni del rendimento specializzate per la ricerca vettoriale.

Utilizzare valori letterali SQL per la clausola LIMIT

Se il limite top-k è fisso, utilizza un valore letterale SQL anziché un parametro. Ad esempio, utilizza LIMIT 10 anziché LIMIT @limit. In questo modo, l'ottimizzatore di query di Spanner dispone di maggiori informazioni per selezionare il piano di esecuzione delle query migliore.

Utilizzare la scansione orientata ai batch

Le query di ricerca vettoriale sono pesanti per la scansione. Per le query KNN, valuta la possibilità di utilizzare la scansione orientata ai batch con il scan_method=batch suggerimento per la query. Questo è il metodo di scansione predefinito per le query ANN.

Utilizzare KNN per set di dati di piccole dimensioni

Se KNN è sufficiente per il budget di latenza, non creare un indice vettoriale. KNN è più preciso, evita i costi di creazione e manutenzione degli indici e può avere un rendimento migliore di ANN quando il numero di righe di input dopo il filtraggio è ridotto.

Accelerare KNN filtrato con un indice secondario

Per migliorare il rendimento di una query KNN filtrata, crea un indice secondario sulla colonna di filtro. Ad esempio, considera la seguente query:

SELECT d.DocId
FROM Documents AS d
WHERE Category = 'toy'
ORDER BY COSINE_DISTANCE(d.DocEmbedding, @vector)
LIMIT 10;

Se il numero di documenti per categoria è inferiore a qualche decina di migliaia e la tua applicazione può accettare una latenza delle query di 100 ms, crea un indice secondario sulla colonna Category. Archivia la colonna DocEmbedding nell'indice:

CREATE INDEX ON Documents(Category) STORING (DocEmbedding);

Questa creazione di indici consente di accelerare la query filtrata.

Utilizzare ANN per set di dati di grandi dimensioni

Se il numero di righe è elevato dopo la valutazione dei filtri, crea un indice vettoriale e utilizza la ricerca ANN. Esistono diverse tecniche per accelerare il filtraggio con ANN:

  • Archivia le colonne di filtro: per abilitare il filtraggio durante l'attraversamento della ricerca vettoriale, archivia le colonne di filtro nell'indice vettoriale. In questo modo, le righe non qualificate possono essere rimosse all'inizio dell'esecuzione.

    CREATE VECTOR INDEX ON Documents(DocEmbedding) STORING(Category);
    
  • Colonne di filtro delle chiavi: per velocizzare il filtraggio per le colonne altamente selettive che rimuovono molti risultati, organizza queste colonne come colonne di chiavi aggiuntive in l'indice vettoriale. Le query che specificano l'uguaglianza esatta (utilizzando l'operatore =) per queste chiavi aggiuntive vengono accelerate maggiormente. L'utilizzo della clausola IN per una qualsiasi di queste chiavi aggiuntive non raggiunge lo stesso livello di accelerazione.

    CREATE VECTOR INDEX ON Documents(DocEmbedding, Category);
    
  • Evita di archiviare colonne di grandi dimensioni o di utilizzarle come chiavi: in questo modo potresti diluire i blocchi di dati per gli embedding, il che potrebbe ridurre l'efficienza di lettura. In alternativa, valuta la possibilità di utilizzare una colonna hash nell'indice e la colonna di grandi dimensioni originale come post-filtro dopo top-k.

  • Crea un indice vettoriale filtrato (parziale):se esegui query solo su un sottoinsieme del set di dati e una condizione di filtro definisce questo sottoinsieme, ad esempio Category = "Tech", crea un indice vettoriale filtrato o parziale.