Gérer des index vectoriels
Ce document explique comment créer et gérer des index vectoriels.
Un index vectoriel est une structure de données conçue pour permettre à la fonction VECTOR_SEARCH
d'effectuer une recherche vectorielle plus efficace sur les embeddings. Lorsque VECTOR_SEARCH
peut utiliser un index vectoriel, la fonction utilise la technique de recherche approximative du voisin le plus proche pour améliorer les performances de recherche, avec un compromis consistant à réduire le rappel, renvoyant ainsi des résultats plus approximatifs.
Rôles et autorisations
Pour créer un index vectoriel, vous devez disposer de l'autorisation IAM bigquery.tables.createIndex
sur la table dans laquelle vous créez l'index. Pour supprimer un index vectoriel, vous devez disposer de l'autorisation bigquery.tables.deleteIndex
. Chacun des rôles IAM prédéfinis suivants inclut les autorisations dont vous avez besoin pour travailler avec les index vectoriels :
- Propriétaire de données BigQuery (
roles/bigquery.dataOwner
) - Éditeur de données BigQuery (
roles/bigquery.dataEditor
)
Créer un index vectoriel
Pour créer un index vectoriel, utilisez l'instruction LDD (langage de définition de données) CREATE VECTOR INDEX
:
Accédez à la page BigQuery.
Dans l'éditeur de requête, sélectionnez un type d'index et exécutez l'une des instructions SQL suivantes :
Pour créer un index vectoriel IVF :
CREATE [ OR REPLACE ] VECTOR INDEX [ IF NOT EXISTS ] INDEX_NAME ON DATASET_NAME.TABLE_NAME(COLUMN_NAME) STORING(STORED_COLUMN_NAME [, ...]) OPTIONS(index_type = "IVF", distance_type = "DISTANCE_TYPE", ivf_options = '{"num_lists":NUM_LISTS}')
Pour créer un index vectoriel TreeAH :
CREATE [ OR REPLACE ] VECTOR INDEX [ IF NOT EXISTS ] INDEX_NAME ON DATASET_NAME.TABLE_NAME(COLUMN_NAME) OPTIONS(index_type = "TREE_AH", distance_type = "DISTANCE_TYPE", tree_ah_options = '{"leaf_node_embedding_count":LEAF_NODE_EMBEDDING_COUNT, "normalization_type":"NORMALIZATION_TYPE"}')
Pour en savoir plus, consultez la section Choisir un type d'index vectoriel.
Remplacez les éléments suivants :
INDEX_NAME
: nom de l'index vectoriel que vous créez. Étant donné que l'index est toujours créé dans le même projet et le même ensemble de données que la table de base, il n'est pas nécessaire de les spécifier dans le nom.DATASET_NAME
: nom de l'ensemble de données contenant la table.TABLE_NAME
: nom de la table contenant la colonne avec des données d'embeddings.COLUMN_NAME
: nom d'une colonne contenant des données d'embeddings. La colonne doit être de typeARRAY<FLOAT64>
. La colonne ne peut pas comporter de champs enfants. Tous les éléments du tableau ne doivent pas êtreNULL
, et toutes les valeurs de la colonne doivent avoir les mêmes dimensions de tableau.STORED_COLUMN_NAME
: nom d'une colonne de premier niveau dans la table à stocker dans l'index vectoriel. Le type de colonne ne peut pas êtreRANGE
. Les colonnes stockées ne sont pas utilisées si la table dispose d'une règle d'accès au niveau des lignes ou si la colonne comporte un tag avec stratégie. Pour savoir comment activer les colonnes stockées, consultez la section Stocker des colonnes et définir un préfiltrage.DISTANCE_TYPE
: spécifie le type de distance par défaut à utiliser lors de l'exécution d'une recherche vectorielle à l'aide de cet index. Les valeurs acceptées sontEUCLIDEAN
,COSINE
etDOT_PRODUCT
.EUCLIDEAN
est la valeur par défaut.La création de l'index elle-même utilise toujours la distance
EUCLIDEAN
pour l'entraînement, mais la distance utilisée dans la fonctionVECTOR_SEARCH
peut être différente.Si vous spécifiez une valeur pour l'argument
distance_type
de la fonctionVECTOR_SEARCH
, cette valeur est utilisée à la place de la valeurDISTANCE_TYPE
.NUM_LISTS
: valeurINT64
inférieure ou égale à 5 000 qui détermine le nombre de listes créées par l'algorithme IVF. L'algorithme IVF divise l'intégralité de l'espace de données en un nombre de listes égal àNUM_LISTS
, les points de données plus proches les uns des autres étant plus susceptibles d'être placés sur la même liste. Si la valeur deNUM_LISTS
est faible, vous obtenez moins de listes avec davantage de points de données, tandis qu'une valeur plus élevée crée davantage de listes avec moins de points de données.Vous pouvez utiliser
NUM_LISTS
en combinaison avec l'argumentfraction_lists_to_search
dans la fonctionVECTOR_SEARCH
pour créer une recherche vectorielle efficace. Si vos données sont distribuées dans de nombreux petits groupes dans l'espace d'embedding, spécifiez une valeurNUM_LISTS
élevée afin de créer un index comportant davantage de listes, et spécifiez une valeurfraction_lists_to_search
plus faible pour avoir moins de listes à analyser lors de la recherche vectorielle. Utilisez une valeurNUM_LISTS
plus faible et une valeurfraction_lists_to_search
plus élevée lorsque vos données sont distribuées dans des groupes plus petits et plus grands. L'utilisation d'une valeurnum_lists
élevée peut ralentir la création de l'index vectoriel.Si vous ne spécifiez pas de valeur
NUM_LISTS
, BigQuery calcule une valeur appropriée.LEAF_NODE_EMBEDDING_COUNT
: valeurINT64
supérieure ou égale à 500, qui spécifie le nombre approximatif de vecteurs dans chaque nœud feuille de l'arborescence créée par l'algorithme TreeAH. L'algorithme TreeAH divise l'intégralité de l'espace de données en un certain nombre de listes, chacune contenant un nombre de points de données correspondant approximativement àLEAF_NODE_EMBEDDING_COUNT
. Une valeur inférieure crée davantage de listes comportant chacune moins de points de données, tandis qu'une valeur plus élevée crée moins de listes, mais avec davantage de points de données. La valeur par défaut est 1 000.NORMALIZATION_TYPE
: une valeurSTRING
. Les valeurs acceptées sontNONE
ouL2
. La valeur par défaut estNONE
. La normalisation intervient avant tout traitement, à la fois pour les données de la table de base et pour les données de requête, mais elle ne modifie pas la colonne d'embeddingCOLUMN_NAME
dans la tableTABLE_NAME
. En fonction de l'ensemble de données, du modèle d'embedding et du type de distance utilisé lors de la rechercheVECTOR_SEARCH
, la normalisation des embeddings peut améliorer le rappel.
L'exemple suivant crée un index vectoriel sur la colonne embedding
de my_table
:
CREATE TABLE my_dataset.my_table(embedding ARRAY<FLOAT64>); CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding) OPTIONS(index_type = 'IVF');
L'exemple suivant crée un index vectoriel sur la colonne embedding
de my_table
et spécifie le type de distance à utiliser et les options IVF :
CREATE TABLE my_dataset.my_table(embedding ARRAY<FLOAT64>); CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding) OPTIONS(index_type = 'IVF', distance_type = 'COSINE', ivf_options = '{"num_lists": 2500}')
L'exemple suivant crée un index vectoriel sur la colonne embedding
de la table my_table
, et spécifie le type de distance à utiliser et les options TreeAH :
CREATE TABLE my_dataset.my_table(id INT64, embedding ARRAY<FLOAT64>); CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding) OPTIONS (index_type = 'TREE_AH', distance_type = 'EUCLIDEAN', tree_ah_options = '{"normalization_type": "L2"}');
Choisir un type d'index vectoriel
BigQuery propose deux types d'index vectoriels.
Index IVF
L'IVF est un index de fichier inversé, qui utilise un algorithme basé sur les k-moyennes pour regrouper les données vectorielles en clusters, puis qui partitionne les données vectorielles en fonction de ces clusters définis. Lorsque vous utilisez la fonction VECTOR_SEARCH
pour rechercher des données vectorielles, elle peut utiliser ces partitions pour réduire la quantité de données à lire afin de déterminer un résultat.
Index TreeAH
TreeAH est un type d'index vectoriel qui utilise l'algorithme ScaNN de Google. Elle fonctionne comme suit :
La table de base est divisée en segments plus petits et plus faciles à gérer.
Un modèle de clustering est entraîné, avec le nombre de clusters dérivé de l'option
leaf_node_embedding_count
danstree_ah_options
.Les vecteurs sont quantifiés par produit et stockés dans les tables d'index.
Lors de la requête
VECTOR_SEARCH
, une liste de candidats pour chaque vecteur de requête est calculée efficacement à l'aide d'un hachage asymétrique, qui bénéficie d'une optimisation matérielle pour les calculs de distance approximative. Ces candidats sont ensuite réévalués et reclassés à l'aide d'embeddings exacts.
L'algorithme TreeAH est optimisé pour les requêtes par lot qui traitent plusieurs centaines de vecteurs de requête, ou plus. L'utilisation de la quantification par produit peut réduire considérablement la latence et les coûts, potentiellement de plusieurs ordres de grandeur par rapport à l'index de fichier inversé (IVF). Toutefois, en raison de la surcharge accrue, l'algorithme IVF peut être plus efficace lorsque vous avez un nombre réduit de vecteurs de requête.
Nous vous suggérons d'essayer le type d'index TreeAH si votre cas d'utilisation répond aux critères suivants :
Votre table ne contient pas plus de 200 millions de lignes.
Vous exécutez fréquemment de grandes requêtes par lot impliquant plusieurs centaines de vecteurs de requête, ou plus.
Pour les petites requêtes par lot, une requête
VECTOR_SEARCH
utilisant le type d'index TreeAH risque de basculer sur une recherche par force brute. Dans ce cas, un motif de non-utilisation de l'index vectoriel est renseigné pour expliquer la raison de ce basculement.Votre workflow ne nécessite pas l'utilisation de colonnes stockées ni de préfiltrage. BigQuery traite les préfiltres utilisés avec un index TreeAH comme des postfiltres.
Pour toute question, en particulier sur l'évolutivité, les limites et les performances, veuillez nous contacter à l'adresse bq-vector-search@google.com.
Stocker des colonnes et définir un préfiltrage
Pour améliorer l'efficacité de votre index vectoriel, vous pouvez spécifier des colonnes de votre table de base à stocker dans votre index vectoriel. L'utilisation de colonnes stockées peut optimiser les requêtes qui appellent la fonction VECTOR_SEARCH
de différentes manières :
La fonction
VECTOR_SEARCH
génère une struct appeléebase
qui contient toutes les colonnes de la table de base. Sans colonnes stockées, une jointure potentiellement coûteuse est nécessaire pour récupérer les colonnes stockées dansbase
. Si votre requête ne sélectionne que les colonnes stockées dansbase
, BigQuery optimise votre requête pour éliminer cette jointure.Au lieu d'effectuer une recherche dans une table entière, vous pouvez appeler la fonction
VECTOR_SEARCH
sur une instruction de requête qui préfiltre la table de base à l'aide d'une clauseWHERE
. Si votre table comporte un indice et que vous ne filtrez que sur les colonnes stockées, BigQuery optimise la requête en filtrant les données avant la recherche, puis en utilisant l'indice pour rechercher l'ensemble de résultats plus petit. Si vous filtrez sur des colonnes qui ne sont pas stockées, BigQuery applique le filtre après la recherche dans la table, ou post-filtres.Le post-filtrage est moins efficace et peut générer moins de
top_k
correspondances dans l'ensemble de résultats. Dans certains cas, le préfiltrage peut également réduire la taille de l'ensemble de résultats. Dans ce cas, essayez d'augmenter la valeur defraction_lists_to_search
lorsque vous appelezVECTOR_SEARCH
.
Pour stocker des colonnes, regroupez-les dans la clause STORING
de l'instruction LDD CREATE VECTOR INDEX
.
Le stockage de colonnes augmente la taille de l'index de vecteur. Il est donc préférable de ne stocker que les colonnes les plus fréquemment utilisées ou filtrées.
L'exemple suivant crée un index vectoriel avec des colonnes stockées, puis explique le comportement des différents types de recherches vectorielles :
-- Create a table that contains an embedding. CREATE TABLE my_dataset.my_table(embedding ARRAY<FLOAT64>, type STRING, creation_time DATETIME, id INT64); -- Create a query table that contains an embedding. CREATE TABLE my_dataset.my_testdata(embedding ARRAY<FLOAT64>, test_id INT64); -- Create a vector index with stored columns. CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding) STORING (type, creation_time) OPTIONS (index_type = 'IVF'); -- Select only stored columns from a vector search to avoid an expensive join. SELECT query, base.type, distance FROM VECTOR_SEARCH( TABLE my_dataset.my_table, 'embedding' TABLE my_dataset.my_testdata); -- Pre-filter on a stored column. The index speeds up the query. SELECT * FROM VECTOR_SEARCH( (SELECT * FROM my_dataset.my_table WHERE type = 'animal'), 'embedding', TABLE my_dataset.my_testdata); -- Filter on a column that isn't stored. The index is used to search the -- entire table, and then the results are post-filtered. You might see fewer -- than 5 matches returned for some embeddings. SELECT query.test_id, base.type, distance FROM VECTOR_SEARCH( (SELECT * FROM my_dataset.my_table WHERE id = 123), 'embedding', TABLE my_dataset.my_testdata, top_k => 5); -- Use post-filters. The index is used, but the entire table is searched and -- the post-filtering might reduce the number of results. SELECT query.test_id, base.type, distance FROM VECTOR_SEARCH( TABLE my_dataset.my_table, 'embedding', TABLE my_dataset.my_testdata, top_k => 5) WHERE base.type = 'animal'; -- Use pre-filters with brute force. The data is filtered and then searched -- with brute force for exact results. SELECT query.test_id, base.type, distance FROM VECTOR_SEARCH( (SELECT * FROM my_dataset.my_table WHERE id = 123), 'embedding', TABLE my_dataset.my_testdata, options => '{"use_brute_force":true}');
Limites
- Vous ne pouvez pas utiliser de vues logiques dans votre pré-filtre.
- Si votre préfiltre contient une sous-requête, cela peut interférer avec l'utilisation de l'index.
- Si le mode, le type ou le schéma d'une colonne est modifié dans la table de base, et s'il s'agit d'une colonne stockée dans l'index vectoriel, il peut y avoir un délai avant que cette modification ne soit reflétée dans l'index vectoriel. Jusqu'à ce que les mises à jour aient été appliquées à l'index, les requêtes de recherche vectorielle utilisent les colonnes stockées modifiées de la table de base.
- Si vous sélectionnez une colonne de type
STRUCT
dans la sortiequery
d'une requêteVECTOR_SEARCH
, portant sur une table comportant un index avec des colonnes stockées, la requête entière peut échouer. - Les colonnes stockées ne sont pas compatibles avec les index TreeAH.
Comprendre l'actualisation de l'index
Les index vectoriels sont entièrement gérés par BigQuery et actualisés automatiquement lorsque la table indexée est modifiée. Si vous supprimez la colonne indexée d'une table ou renommez la table elle-même, l'index vectoriel est automatiquement supprimé.
Si vous créez un index vectoriel sur une table de taille inférieure à 10 Mo, l'index vectoriel n'est pas renseigné. De même, si vous supprimez les données d'une table indexée et que sa taille est inférieure à 10 Mo, l'index vectoriel est temporairement désactivé. Dans ce cas, les requêtes de recherche vectorielle n'utilisent pas l'index et le code indexUnusedReasons
de la section vectorSearchStatistics
de la ressource Job
est BASE_TABLE_TOO_SMALL
. Sans l'index, la requête VECTOR_SEARCH
bascule automatiquement sur la recherche par force brute pour identifier les voisins les plus proches des embeddings.
Les requêtes qui utilisent la fonction VECTOR_SEARCH
renvoient toujours des résultats corrects, même si une partie des données n'est pas encore indexée.
En savoir plus sur les index vectoriels
Vous pouvez vérifier l'existence et la disponibilité d'un index vectoriel en interrogeant INFORMATION_SCHEMA
. Les vues suivantes contiennent des métadonnées sur des index vectoriels :
La vue
INFORMATION_SCHEMA.VECTOR_INDEXES
contient des informations sur les index vectoriels d'un ensemble de données.Une fois l'instruction
CREATE VECTOR INDEX
terminée, vous devez renseigner l'index pour pouvoir l'utiliser. Vous pouvez utiliser les colonneslast_refresh_time
etcoverage_percentage
pour vérifier la disponibilité d'un indice vectoriel. Si l'index vectoriel n'est pas prêt, vous pouvez toujours utiliser la fonctionVECTOR_SEARCH
sur une table. En revanche, elle peut s'exécuter plus lentement sans l'index.La vue
INFORMATION_SCHEMA.VECTOR_INDEX_COLUMNS
contient des informations sur les colonnes dotées d'un index vectoriel pour toutes les tables d'un ensemble de données.La vue
INFORMATION_SCHEMA.VECTOR_INDEX_OPTIONS
contient des informations sur les options utilisées par les index vectoriels d'un ensemble de données.
Exemples d'index vectoriels
L'exemple suivant montre tous les index vectoriels actifs sur les tables de l'ensemble de données my_dataset
, situées dans le projet my_project
. Cela inclut leur nom, les instructions LDD utilisées pour les créer et leur pourcentage de couverture. Si une table de base indexée est inférieure à 10 Mo, son index n'est pas renseigné, auquel cas la valeur de coverage_percentage
est égale à 0.
SELECT table_name, index_name, ddl, coverage_percentage FROM my_project.my_dataset.INFORMATION_SCHEMA.VECTOR_INDEXES WHERE index_status = 'ACTIVE';
Le résultat ressemble à ce qui suit :
+------------+------------+-------------------------------------------------------------------------------------------------+---------------------+ | table_name | index_name | ddl | coverage_percentage | +------------+------------+-------------------------------------------------------------------------------------------------+---------------------+ | table1 | indexa | CREATE VECTOR INDEX `indexa` ON `my_project.my_dataset.table1`(embeddings) | 100 | | | | OPTIONS (distance_type = 'EUCLIDEAN', index_type = 'IVF', ivf_options = '{"num_lists": 100}') | | +------------+------------+-------------------------------------------------------------------------------------------------+---------------------+ | table2 | indexb | CREATE VECTOR INDEX `indexb` ON `my_project.my_dataset.table2`(vectors) | 42 | | | | OPTIONS (distance_type = 'COSINE', index_type = 'IVF', ivf_options = '{"num_lists": 500}') | | +------------+------------+-------------------------------------------------------------------------------------------------+---------------------+ | table3 | indexc | CREATE VECTOR INDEX `indexc` ON `my_project.my_dataset.table3`(vectors) | 98 | | | | OPTIONS (distance_type = 'DOT_PRODUCT', index_type = 'TREE_AH', | | | | | tree_ah_options = '{"leaf_node_embedding_count": 1000, "normalization_type": "NONE"}') | | +------------+------------+-------------------------------------------------------------------------------------------------+---------------------+
Exemples de colonnes d'index vectoriels
La requête suivante extrait des informations sur les colonnes comportant des index vectoriels :
SELECT table_name, index_name, index_column_name, index_field_path FROM my_project.dataset.INFORMATION_SCHEMA.VECTOR_INDEX_COLUMNS;
Le résultat ressemble à ce qui suit :
+------------+------------+-------------------+------------------+ | table_name | index_name | index_column_name | index_field_path | +------------+------------+-------------------+------------------+ | table1 | indexa | embeddings | embeddings | | table2 | indexb | vectors | vectors | | table3 | indexc | vectors | vectors | +------------+------------+-------------------+------------------+
Exemples d'options d'index vectoriels
La requête suivante extrait des informations sur les options d'index vectoriels :
SELECT table_name, index_name, option_name, option_type, option_value FROM my_project.dataset.INFORMATION_SCHEMA.VECTOR_INDEX_OPTIONS;
Le résultat ressemble à ce qui suit :
+------------+------------+------------------+------------------+-------------------------------------------------------------------+ | table_name | index_name | option_name | option_type | option_value | +------------+------------+------------------+------------------+-------------------------------------------------------------------+ | table1 | indexa | index_type | STRING | IVF | | table1 | indexa | distance_type | STRING | EUCLIDEAN | | table1 | indexa | ivf_options | STRING | {"num_lists": 100} | | table2 | indexb | index_type | STRING | IVF | | table2 | indexb | distance_type | STRING | COSINE | | table2 | indexb | ivf_options | STRING | {"num_lists": 500} | | table3 | indexc | index_type | STRING | TREE_AH | | table3 | indexc | distance_type | STRING | DOT_PRODUCT | | table3 | indexc | tree_ah_options | STRING | {"leaf_node_embedding_count": 1000, "normalization_type": "NONE"} | +------------+------------+------------------+------------------+-------------------------------------------------------------------+
Utilisation de l'index vectoriel
Des informations sur l'utilisation des index vectoriels sont disponibles dans les métadonnées du job qui a exécuté la requête de recherche vectorielle. Vous pouvez afficher les métadonnées du job à l'aide de la console Google Cloud, de l'outil de ligne de commande bq, de l'API BigQuery ou des bibliothèques clientes.
Lorsque vous utilisez la console Google Cloud, vous pouvez trouver des informations sur l'utilisation des index vectoriels dans les champs Mode d'utilisation de l'index vectoriel et Motifs de non-utilisation de l'index vectoriel.
Lorsque vous utilisez l'outil bq ou l'API BigQuery, vous pouvez trouver des informations sur l'utilisation de l'index vectoriel dans la section VectorSearchStatistics
de la ressource Job
.
Le mode d'utilisation de l'index indique si un index vectoriel a été utilisé en fournissant l'une des valeurs suivantes :
UNUSED
: aucun index vectoriel n'a été utilisé.PARTIALLY_USED
: certaines fonctionsVECTOR_SEARCH
de la requête utilisaient des index vectoriels, et d'autres non.FULLY_USED
: chaque fonctionVECTOR_SEARCH
de la requête a utilisé un index vectoriel.
Lorsque la valeur du mode d'utilisation de l'index est UNUSED
ou PARTIALLY_USED
, les motifs de non-utilisation de l'index indiquent pourquoi les index vectoriels n'ont pas été utilisés dans la requête.
Par exemple, les résultats suivants renvoyés par bq show --format=prettyjson -j my_job_id
indiquent que l'index n'a pas été utilisé, car l'option use_brute_force
a été spécifiée dans la fonction VECTOR_SEARCH
:
"vectorSearchStatistics": { "indexUnusedReasons": [ { "baseTable": { "datasetId": "my_dataset", "projectId": "my_project", "tableId": "my_table" }, "code": "INDEX_SUPPRESSED_BY_FUNCTION_OPTION", "message": "No vector index was used for the base table `my_project:my_dataset.my_table` because use_brute_force option has been specified." } ], "indexUsageMode": "UNUSED" }
Options de gestion des index
Pour créer des index et laisser BigQuery les gérer, deux options s'offrent à vous :
- Utiliser le pool d'emplacements partagés par défaut : lorsque les données que vous prévoyez d'indexer sont inférieures à votre limite par organisation, vous pouvez utiliser le pool d'emplacements partagé gratuit pour la gestion des index.
- Utiliser votre propre réservation : pour obtenir une progression d'indexation plus prévisible et cohérente sur vos charges de travail de production plus importantes, vous pouvez utiliser vos propres réservations pour la gestion des index.
Utiliser les emplacements partagés
Si vous n'avez pas configuré votre projet pour utiliser une réservation dédiée pour l'indexation, la gestion des index est gérée dans le pool d'emplacements partagés gratuit, qui est soumis aux contraintes suivantes.
Si vous ajoutez des données à une table, ce qui entraîne le dépassement de la limite des tables indexées pour votre organisation, BigQuery suspend la gestion des index pour toutes les tables indexées. Dans ce cas, le champ index_status
de la vue INFORMATION_SCHEMA.VECTOR_INDEXES
affiche PENDING DISABLEMENT
et l'index est mis en file d'attente pour suppression. Tant que l'index est en attente de désactivation, il est toujours utilisé dans les requêtes et le stockage des index vous est facturé.
Une fois l'index supprimé, le champ index_status
affiche l'état de l'index comme étant TEMPORARILY DISABLED
. Dans cet état, les requêtes n'utilisent pas l'index et le stockage d'index ne vous est pas facturé. Dans ce cas, le code IndexUnusedReason
est BASE_TABLE_TOO_LARGE
.
Si vous supprimez des données de la table et que la taille totale des tables indexées est inférieure à la limite par organisation, la gestion des index est réactivée pour toutes les tables indexées. Le champ index_status
dans la vue INFORMATION_SCHEMA.VECTOR_INDEXES
est ACTIVE
, les requêtes peuvent utiliser l'index et le stockage d'index vous est facturé.
BigQuery ne garantit pas la capacité disponible du pool partagé ni le débit d'indexation que vous voyez. Pour les applications de production, vous pouvez utiliser des emplacements dédiés pour le traitement des index.
Utiliser votre propre réservation
Au lieu d'utiliser le pool d'emplacements partagés par défaut, vous pouvez éventuellement définir votre propre réservation pour indexer vos tables. L'utilisation de votre propre réservation garantit des performances prévisibles et cohérentes pour les jobs de gestion des index, telles que la création, l'actualisation et les optimisations en arrière-plan.
- Il n'y a aucune limite de taille de table lorsqu'un job d'indexation s'exécute dans votre réservation.
- L'utilisation de votre propre réservation vous donne une certaine flexibilité dans la gestion de vos index. Si vous devez créer un index très volumineux ou effectuer une mise à jour majeure d'une table indexée, vous pouvez ajouter temporairement d'autres emplacements à l'attribution.
Pour indexer les tables d'un projet avec une réservation désignée, créez une réservation dans la région où se trouvent vos tables. Ensuite, attribuez le projet à la réservation en définissant job_type
sur BACKGROUND
:
SQL
Utilisez l'instruction LDD CREATE ASSIGNMENT
:
Dans la console Google Cloud, accédez à la page BigQuery.
Dans l'éditeur de requête, saisissez l'instruction suivante :
CREATE ASSIGNMENT `ADMIN_PROJECT_ID.region-LOCATION.RESERVATION_NAME.ASSIGNMENT_ID` OPTIONS ( assignee = 'projects/PROJECT_ID', job_type = 'BACKGROUND');
Remplacez les éléments suivants :
ADMIN_PROJECT_ID
: ID du projet d'administration propriétaire de la ressource de réservationLOCATION
: emplacement de la réservation.RESERVATION_NAME
: nom de la réservationASSIGNMENT_ID
: ID de l'attributionL'ID doit être unique au projet et à l'emplacement. Il doit commencer et se terminer par une lettre minuscule ou un chiffre, et ne doit contenir que des lettres minuscules, des chiffres et des tirets.
PROJECT_ID
: ID du projet contenant les tables à indexer. Ce projet est attribué à la réservation.
Cliquez sur
Exécuter.
Pour en savoir plus sur l'exécution des requêtes, consultez Exécuter une requête interactive.
bq
Exécutez la commande bq mk
:
bq mk \ --project_id=ADMIN_PROJECT_ID \ --location=LOCATION \ --reservation_assignment \ --reservation_id=RESERVATION_NAME \ --assignee_id=PROJECT_ID \ --job_type=BACKGROUND \ --assignee_type=PROJECT
Remplacez les éléments suivants :
ADMIN_PROJECT_ID
: ID du projet d'administration propriétaire de la ressource de réservationLOCATION
: emplacement de la réservation.RESERVATION_NAME
: nom de la réservationPROJECT_ID
: ID du projet à attribuer à cette réservation
Afficher vos tâches d'indexation
Un job d'indexation est créée chaque fois qu'un index est créé ou mis à jour sur une table unique. Pour afficher des informations sur la tâche, interrogez les vues INFORMATION_SCHEMA.JOBS*
. Vous pouvez filtrer les tâches d'indexation en définissant job_type IS NULL AND SEARCH(job_id, '`search_index`')
dans la clause WHERE
de votre requête. L'exemple suivant répertorie les cinq tâches d'indexation les plus récentes du projet my_project
:
SELECT * FROM region-us.INFORMATION_SCHEMA.JOBS WHERE project_id = 'my_project' AND job_type IS NULL AND SEARCH(job_id, '`search_index`') ORDER BY creation_time DESC LIMIT 5;
Choisir votre taille de réservation
Pour choisir le nombre approprié d'emplacements pour votre réservation, vous devez prendre en compte le moment où les tâches de gestion des index sont exécutées, ainsi que le nombre d'emplacements utilisés et votre utilisation au fil du temps. BigQuery déclenche une tâche de gestion des index dans les situations suivantes :
- Vous créez un index sur une table.
- Des données sont modifiées dans une table indexée.
- Le schéma d'une table change, ce qui affecte les colonnes indexées.
- Les données et les métadonnées d'index sont régulièrement optimisées ou mises à jour.
Le nombre d'emplacements dont vous avez besoin pour exécuter une tâche de gestion des index sur une table dépend des facteurs suivants :
- Taille de la table
- Taux d'ingestion de données dans la table
- Taux d'instructions LMD appliquées à la table
- Délai acceptable pour créer et gérer l'index
- Complexité de l'index, généralement déterminée par les attributs des données, tels que le nombre de termes en double
Surveiller l'utilisation et la progression
Le meilleur moyen d'évaluer le nombre d'emplacements dont vous avez besoin pour exécuter efficacement vos tâches de gestion des index consiste à surveiller l'utilisation des emplacements et à ajuster la taille de la réservation en conséquence. La requête suivante permet d'obtenir l'utilisation quotidienne des emplacements pour les tâches de gestion des index. Seuls les 30 derniers jours sont inclus dans la région us-west1
:
SELECT TIMESTAMP_TRUNC(job.creation_time, DAY) AS usage_date, -- Aggregate total_slots_ms used for index-management jobs in a day and divide -- by the number of milliseconds in a day. This value is most accurate for -- days with consistent slot usage. SAFE_DIVIDE(SUM(job.total_slot_ms), (1000 * 60 * 60 * 24)) AS average_daily_slot_usage FROM `region-us-west1`.INFORMATION_SCHEMA.JOBS job WHERE project_id = 'my_project' AND job_type IS NULL AND SEARCH(job_id, '`search_index`') GROUP BY usage_date ORDER BY usage_date DESC limit 30;
Lorsque les emplacements sont insuffisants pour exécuter des tâches de gestion des index, un index peut ne plus être synchronisé avec sa table. Par conséquent, les tâches d'indexation peuvent échouer. Dans ce cas, BigQuery recrée l'index à partir de zéro. Pour éviter la désynchronisation d'index, assurez-vous de disposer de suffisamment d'emplacements pour gérer les mises à jour d'index liées à l'ingestion et à l'optimisation des données. Pour en savoir plus sur l'utilisation des emplacements, consultez la page Graphiques de ressources pour les administrateurs.
Supprimer un index vectoriel
Lorsque vous n'avez plus besoin d'un index vectoriel ou que vous souhaitez modifier la colonne indexée sur une table, vous pouvez supprimer l'index de cette table à l'aide de l'instruction LDD DROP VECTOR INDEX
.
Exemple :
DROP VECTOR INDEX my_index ON my_dataset.indexed_table;
Si une table indexée est supprimée, son index est automatiquement supprimé.
Étapes suivantes
- Pour obtenir une présentation des cas d'utilisation de l'index vectoriel, des tarifs et des limites, consultez la page Présentation de Vector Search.
- Suivez le tutoriel Rechercher des embeddings à l'aide de la recherche vectorielle.