Cette page explique comment créer un index vectoriel et interroger des représentations vectorielles continues de vecteurs en utilisant en utilisant la distance de cosinus approximative, la distance euclidienne approximative et fonctions de vecteur approximative de produit scalaire. Vous pouvez utiliser ces pour trouver les voisins les plus proches (ANN) dans Spanner. Lorsqu'un ensemble de données est de petite taille, vous pouvez utiliser les plus proches k voisins (KNN). pour trouver les vecteurs k les plus proches exacts. Cependant, à mesure que votre ensemble de données s'agrandit, la latence et le coût d'une recherche sur KNN augmentent également. Vous pouvez utiliser un ANN pour obtenir k voisins les plus proches avec une latence et des coûts considérablement réduits.
Nombre approximatif de k voisins les plus proches
Dans une recherche ANN, les k vecteurs renvoyés ne sont pas les k k-valeurs les plus proches les plus proches. entre voisins. Parfois, quelques vecteurs qui ne figurent pas parmi les k premiers k les plus proches les voisins sont renvoyés. C'est ce que l'on appelle la perte de rappel. Quelle est la perte de rappel ? acceptable pour vous dépend du cas d'utilisation, mais dans la plupart des cas, en échange d'une amélioration des performances de la base de données est une un compromis.
Pour en savoir plus sur les fonctions de distance approximative de Spanner, voir:
APPROX_COSINE_DISTANCE
dans GoogleSQLAPPROX_EUCLIDEAN_DISTANCE
dans GoogleSQLAPPROX_DOT_PRODUCT
dans GoogleSQL
Index vectoriel
Spanner accélère les recherches vectorielles ANN en utilisant une requête et un index vectoriel. Cet index s'appuie sur l'outil Scalable Voisin (ScaNN), un algorithme très efficace des voisins les plus proches.
L'index vectoriel utilise une structure arborescente pour partitionner les données et faciliter des recherches plus rapides. Spanner propose à la fois Configurations en arborescence:
- Configuration d'arborescence à deux niveaux: les nœuds feuille (
num_leaves
) contiennent des groupes de de vecteurs étroitement liés et de leur centroïde correspondant. La racine se compose des centroïdes de tous les nœuds feuilles. - Arborescence à trois niveaux: conceptuelle semblable à une arborescence à deux niveaux,
ajout d'une couche de ramification (
num_branches
), à partir de laquelle le nœud feuille les centroïdes sont ensuite partitionnés pour former le niveau racine (num_leaves
).
En outre, vous devez créer votre index vectoriel avec une métrique de distance spécifique.
Vous pouvez choisir la métrique de distance la plus adaptée à votre cas d'utilisation en définissant
distance_type
sur COSINE
, DOT_PRODUCT
ou EUCLIDEAN
.
Pour en savoir plus, consultez Instructions VECTOR INDEX
.
Limites
L'index vectoriel Spanner présente les limites suivantes:
ALTER VECTOR INDEX
n'est pas compatible.
Créer un index vectoriel
Pour optimiser au mieux l'index vectoriel afin d'obtenir un bon rappel et de bonnes performances, nous recommandons créer votre index vectoriel une fois que la plupart des lignes avec des représentations vectorielles continues ont été écrits dans votre base de données. Vous devrez peut-être aussi régulièrement de recréer l'index vectoriel après avoir inséré de nouvelles données. Pour en savoir plus, consultez Reconstruisez l'index vectoriel.
Pour créer un index vectoriel avec une arborescence à deux niveaux et 1 000 nœuds feuilles sur un
Table Documents
avec une colonne de représentation vectorielle continue DocEmbedding
utilisant le cosinus
distance:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(DocEmbedding),
OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);
Pour créer un index vectoriel avec une arborescence à trois niveaux et 1 000 000 nœuds feuilles:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(NullableDocEmbedding)
WHERE NullableDocEmbedding IS NOT NULL
OPTIONS (distance_type = 'COSINE', tree_depth = 3, num_branches=1000, num_leaves = 1000000);
Si votre colonne de représentations vectorielles continues peut avoir une valeur nulle, vous devez la déclarer avec une
Clause WHERE column_name IS NOT NULL
:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(NullableDocEmbedding)
WHERE NullableDocEmbedding IS NOT NULL
OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);
Interroger les embeddings vectoriels
Pour interroger un index vectoriel, utilisez l'une des trois fonctions de distance approximative:
APPROX_COSINE_DISTANCE
APPROX_EUCLIDEAN_DISTANCE
APPROX_DOT_PRODUCT
Lorsque vous utilisez les fonctions de distance approximative, certaines restrictions s'appliquent, entre autres : suivantes:
- Vous devez fournir un indice de requête pour utiliser l'index vectoriel.
- Vous devez utiliser une expression constante comme argument de la fonction de distance (un paramètre ou un littéral, par exemple).
- La requête ou sous-requête dans laquelle la fonction de distance approximative est utilisée doit
prennent une forme spécifique: la fonction de distance doit être la seule touche
ORDER BY
, et une limite doit être spécifiée.
Pour obtenir la liste détaillée des limites, consultez les page de référence sur la fonction de distance approximative.
Exemple
Pour rechercher les 100 vecteurs les plus proches de [1.0, 2.0, 3.0]
:
SELECT DocId
FROM Documents@{FORCE_INDEX=DocEmbeddingIndex}
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
Si la colonne de représentations vectorielles continues peut avoir une valeur nulle:
SELECT DocId
FROM Documents@{FORCE_INDEX=DocEmbeddingIndex}
WHERE NullableDocEmbedding IS NOT NULL
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
Bonnes pratiques
Suivez ces bonnes pratiques pour optimiser vos index vectoriels et améliorer les requêtes résultats.
Ajuster les options de la recherche vectorielle
La valeur optimale de la recherche vectorielle dépend du cas d'utilisation : le vecteur et sur les vecteurs de requête. Vous devrez peut-être effectuer un réglage itératif pour trouver les valeurs les plus adaptées à votre charge de travail.
Voici quelques consignes utiles à suivre lors du choix des valeurs appropriées:
tree_depth
(arborescence): si la table en cours d'indexation comporte moins de 10 millions de lignes, utilisez unetree_depth
de2
. Sinon, unetree_depth
de3
accepte des tables contenant jusqu'à 10 milliards de lignes.num_leaves
: utilise la racine carrée du nombre de lignes dans l'ensemble de données. A peut augmenter la durée de compilation de l'index vectoriel. Éviter de définirnum_leaves
supérieure àtable_row_count/1000
, car les feuilles sont alors trop petites et de mauvaises performances.num_leaves_to_search
: cette option spécifie le nombre de nœuds feuilles de l'index font l'objet d'une recherche. Augmenternum_leaves_to_search
améliore le rappel, mais aussi augmente la latence et les coûts. Nous vous recommandons d'utiliser un nombre représentant 1% du total nombre de feuilles défini dans l'instructionCREATE VECTOR INDEX
comme valeur pournum_leaves_to_search
. Si vous utilisez une clause de filtre, augmentez cette valeur pour élargir la recherche.
Si le rappel est acceptable, mais que le coût de l'interrogation est trop élevé,
ce qui entraîne un faible nombre maximal de RPS, essayez d'augmenter num_leaves
en suivant ces
étapes:
- Définissez
num_leaves
sur plusieurs "k" de sa valeur d'origine (par exemple,2 * sqrt(table_row_count)
). - Définissez
num_leaves_to_search
de sorte qu'il soit identique à la valeur "k" de sa valeur d'origine. - Testez la réduction des
num_leaves_to_search
pour améliorer le coût et le nombre de RPS tout en maintenant le rappel.
Améliorer le rappel
Il existe plusieurs possibilités d'aggravation du rappel, dont les suivantes:
num_leaves_to_search
est trop petit: il peut s'avérer plus difficile de trouver les voisins les plus proches pour certains vecteurs de requête.num_leaves_to_search
pour rechercher plus de feuilles peut contribuer à améliorer le rappel. Récents les requêtes ont peut-être changé pour contenir davantage de ces vecteurs difficiles.L'index vectoriel doit être recompilé: l'arborescence de l'index vectoriel est optimisé pour l'ensemble de données au moment de la création, puis statique. Par conséquent, si des vecteurs très différents sont ajoutés après la création de la l'index vectoriel initial, la structure arborescente risque d'être sous-optimale, un souvenir publicitaire moins important.
Reconstruire l'index vectoriel
Pour reconstruire votre index vectoriel sans temps d'arrêt:
- Créer un index vectoriel sur la même colonne de représentation vectorielle continue que le vecteur actuel
en mettant à jour les paramètres (par exemple,
OPTIONS
) le cas échéant. - Une fois l'index créé, modifiez l'indice
FORCE_INDEX
. à pointer vers le nouvel index pour mettre à jour la requête de recherche vectorielle. Cela garantit que la requête utilise le nouvel index vectoriel. (Vous devrez peut-être aussi réglernum_leaves_to_search
dans votre nouvelle requête). - Supprimez l'index vectoriel obsolète.
Étape suivante
Apprenez-en plus sur les fonctions GoogleSQL
APPROXIMATE_COSINE_DISTANCE()
,APPROXIMATE_EUCLIDEAN_DISTANCE()
etAPPROXIMATE_DOT_PRODUCT()
.Apprenez-en davantage sur les instructions
VECTOR INDEX
GoogleSQL.