Cette page explique comment créer et gérer des index vectoriels Spanner, qui utilisent la recherche approximative du voisin le plus proche (ANN) et des structures arborescentes pour accélérer les recherches de similarité vectorielle dans vos données.
Spanner accélère les recherches vectorielles du voisin le plus proche approximatives (ANN) en utilisant un index vectoriel spécialisé. Cet index s'appuie sur Scalable Nearest Neighbor (ScaNN), un algorithme de recherche du voisin le plus proche très efficace développé par Google Research.
L'index vectoriel utilise une structure arborescente pour partitionner les données et faciliter des recherches plus rapides. Spanner propose des configurations d'arborescence à deux et trois niveaux :
- Configuration de l'arborescence à deux niveaux : les nœuds feuilles (
num_leaves
) contiennent des groupes de vecteurs étroitement liés ainsi que leur centroïde correspondant. Le niveau racine se compose des centroïdes de tous les nœuds feuilles. - Configuration d'arborescence à trois niveaux : semblable à une arborescence à deux niveaux, mais avec une couche de branche supplémentaire (
num_branches
) à partir de laquelle les centroïdes des nœuds feuilles sont partitionnés pour former le niveau racine (num_leaves
).
Spanner choisit un index pour vous. Toutefois, si vous savez qu'un index spécifique fonctionne mieux, vous pouvez utiliser l'indication FORCE_INDEX
pour choisir l'index vectoriel le plus adapté à votre cas d'utilisation.
Pour en savoir plus, consultez la section Instructions VECTOR INDEX
.
Limites
- Vous ne pouvez pas pré-fractionner les index vectoriels. Pour en savoir plus, consultez Présentation du pré-fractionnement.
Créer un index vectoriel
Pour optimiser le rappel et les performances d'un index vectoriel, nous vous recommandons de :
Créez votre index vectoriel une fois que la plupart des lignes avec des embeddings ont été écrites dans votre base de données. Vous devrez peut-être aussi reconstruire périodiquement l'index vectoriel après avoir inséré de nouvelles données. Pour en savoir plus, consultez Reconstruire l'index vectoriel.
Utilisez la clause
STORING
pour stocker une copie d'une colonne dans l'index vectoriel. Si une valeur de colonne est stockée dans l'index vectoriel, Spanner effectue le filtrage au niveau de la feuille de l'index pour améliorer les performances des requêtes. Nous vous recommandons de stocker une colonne si elle est utilisée dans une condition de filtrage. Pour en savoir plus sur l'utilisation deSTORING
dans un index, consultez Créer un index pour les analyses d'index uniquement.
Lorsque vous créez votre table, la colonne d'intégration doit être un tableau de type de données FLOAT32
(recommandé) ou FLOAT64
, et comporter une annotation vector_length indiquant la dimension des vecteurs.
L'instruction LDD suivante crée une table Documents
avec une colonne d'embedding DocEmbedding
avec une longueur de vecteur :
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING (1024),
DocContents Bytes(MAX),
DocEmbedding ARRAY<FLOAT32>(vector_length=>128) NOT NULL,
NullableDocEmbedding ARRAY<FLOAT32>(vector_length=>128),
WordCount INT64,
) PRIMARY KEY (DocId);
Une fois que vous avez rempli votre table Documents
, vous pouvez créer un index vectoriel avec un arbre à deux niveaux et 1 000 nœuds feuilles sur la table Documents
avec une colonne d'intégration DocEmbedding
à l'aide de la distance cosinus :
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(DocEmbedding)
STORING (WordCount)
OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);
Si votre colonne d'intégration n'est pas marquée comme NOT NULL
dans la définition de la table, vous devez la déclarer avec une clause WHERE COLUMN_NAME IS NOT NULL
dans la définition de l'index vectoriel, où COLUMN_NAME
est le nom de votre colonne d'intégration. Pour créer un index vectoriel avec un arbre à trois niveaux et 1 000 000 de nœuds feuilles sur la colonne d'embedding pouvant être nulle NullableDocEmbedding
à l'aide de la distance cosinus :
CREATE VECTOR INDEX DocEmbeddingThreeLevelIndex
ON Documents(NullableDocEmbedding)
STORING (WordCount)
WHERE NullableDocEmbedding IS NOT NULL
OPTIONS (distance_type = 'COSINE', tree_depth = 3, num_branches=1000, num_leaves = 1000000);
Filtrer un index vectoriel
Vous pouvez également créer un index vectoriel filtré pour trouver les éléments les plus similaires de votre base de données qui correspondent à la condition de filtre. Un index vectoriel filtré indexe de manière sélective les lignes qui répondent aux conditions de filtre spécifiées, ce qui améliore les performances de recherche.
Dans l'exemple suivant, la table Documents2
comporte une colonne appelée Category
.
Dans notre recherche vectorielle, nous souhaitons indexer la catégorie "Tech". Nous créons donc une colonne générée qui renvoie NULL
si la condition de catégorie n'est pas remplie.
CREATE TABLE Documents2 (
DocId INT64 NOT NULL,
Category STRING(MAX),
NullIfFiltered BOOL AS (IF(Category = 'Tech', TRUE, NULL)) HIDDEN,
DocEmbedding ARRAY<FLOAT32>(vector_length=>128),
) PRIMARY KEY (DocId);
Ensuite, nous créons un index vectoriel avec un filtre. L'index vectoriel TechDocEmbeddingIndex
n'indexe que les documents de la catégorie "Tech".
CREATE VECTOR INDEX TechDocEmbeddingIndex
ON Documents2(DocEmbedding)
STORING(NullIfFiltered)
WHERE DocEmbedding IS NOT NULL AND NullIfFiltered IS NOT NULL
OPTIONS (...);
Lorsque Spanner exécute la requête suivante, qui comporte des filtres correspondant à TechDocEmbeddingIndex
, il sélectionne automatiquement TechDocEmbeddingIndex
et est accéléré par cette requête. La requête ne recherche que les documents de la catégorie "Tech". Vous pouvez également utiliser {@FORCE_INDEX=TechDocEmbeddingIndex}
pour forcer Spanner à utiliser explicitement TechDocEmbeddingIndex
.
SELECT *
FROM Documents2
WHERE DocEmbedding IS NOT NULL AND NullIfFiltered IS NOT NULL
ORDER BY APPROX_(....)
LIMIT 10;
Étapes suivantes
En savoir plus sur les plus proches voisins approximatifs de Spanner
En savoir plus sur les fonctions GoogleSQL
APPROXIMATE_COSINE_DISTANCE()
,APPROXIMATE_EUCLIDEAN_DISTANCE()
etAPPROXIMATE_DOT_PRODUCT()
En savoir plus sur les instructions
VECTOR INDEX
GoogleSQLEn savoir plus sur les bonnes pratiques concernant les index vectoriels