Administra índices vectoriales

En este documento, se describe cómo crear y administrar índices vectoriales.

Un índice vectorial es una estructura de datos diseñada para permitir que la función VECTOR_SEARCH realice una búsqueda de vectores más eficiente de las incorporaciones. Cuando VECTOR_SEARCH puede usar un índice vectorial, la función usa la técnica de búsqueda del vecino más cercano aproximado para ayudar a mejorar el rendimiento de la búsqueda a cambio de reducir la recuperación y, por lo tanto, muestra resultados más aproximados.

Funciones y permisos

Para crear un índice vectorial, necesitas el permiso de IAM bigquery.tables.createIndex en la tabla en la que creas el índice. Para descartar un índice vectorial, necesitas el permiso bigquery.tables.deleteIndex. Cada uno de los siguientes roles predefinidos de IAM incluye los permisos que necesitas para trabajar con índices vectoriales:

  • Propietario de datos de BigQuery (roles/bigquery.dataOwner)
  • Editor de datos de BigQuery (roles/bigquery.dataEditor)

Crea un índice vectorial

Para crear un índice vectorial, usa la declaración de lenguaje de definición de datos (DDL) CREATE VECTOR INDEX:

  1. Ve a la página de BigQuery.

    Ir a BigQuery

  2. En el editor de consultas, selecciona un tipo de índice y ejecuta las siguientes instrucciones de SQL:

    Para crear un índice vectorial IVF, haz lo siguiente:

    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}')

    Para crear un índice vectorial de TreeAH, sigue estos pasos:

    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"}')

    Consulta Elige un tipo de índice vectorial para obtener más información.

    Reemplaza lo siguiente:

    • INDEX_NAME: es el nombre del índice vectorial que creas. Debido a que el índice siempre se crea en el mismo proyecto y conjunto de datos que la tabla base, no es necesario especificarlos en el nombre.
    • DATASET_NAME: es el nombre del conjunto de datos que contiene la tabla.
    • TABLE_NAME: es el nombre de la tabla que contiene la columna con datos de incorporaciones.
    • COLUMN_NAME: es el nombre de una columna que contiene los datos de las incorporaciones. La columna debe tener un tipo de ARRAY<FLOAT64>. La columna no puede tener ningún campo secundario. Todos los elementos del array deben ser distintos de NULL y todos los valores de la columna deben tener las mismas dimensiones de array.
    • STORED_COLUMN_NAME: Es el nombre de una columna de nivel superior en la tabla que se almacenará en el índice vectorial El tipo de columna no puede serRANGE. Las columnas almacenadas no se usan si la tabla tiene una política de acceso a nivel de las filas o si la columna tiene una etiqueta de política. Para obtener información sobre cómo habilitar las columnas almacenadas, consulta Almacena columnas y un filtro previo.
    • DISTANCE_TYPE: especifica el tipo de distancia predeterminado que se usará cuando se realice una búsqueda vectorial mediante este índice. Los valores admitidos son EUCLIDEAN, COSINE y DOT_PRODUCT. EUCLIDEAN es la configuración predeterminada.

      La creación del índice siempre usa la distancia EUCLIDEAN para el entrenamiento, pero la distancia que se usa en la función VECTOR_SEARCH puede ser diferente.

      Si especificas un valor para el argumento distance_type de la función VECTOR_SEARCH, se usa ese valor en lugar del valor DISTANCE_TYPE.

    • NUM_LISTS: un valor INT64 menor o igual que 5,000 que determina cuántas listas crea el algoritmo de IVF. El algoritmo IVF divide todo el espacio de datos en una cantidad de listas igual a NUM_LISTS, y los datos que están más cerca entre sí tienen más probabilidades de incluirse en la misma lista. Si NUM_LISTS es pequeño, tienes menos listas con más datos, mientras que un valor mayor crea más listas con menos datos.

      Puedes usar NUM_LISTS junto con el argumento fraction_lists_to_search en la función VECTOR_SEARCH para crear una búsqueda de vectores eficiente. Si tienes datos que se distribuyen en muchos grupos pequeños en el espacio de incorporaciones, especifica un NUM_LISTS alto para crear un índice con más listas y especifica un valor fraction_lists_to_search más bajo para analizar menos listas en la búsqueda vectorial. Usa un valor de NUM_LISTS más bajo y un valor de fraction_lists_to_search más alto cuando tus datos se distribuyan en menos grupos, más grandes. El uso de un valor num_lists alto puede hacer que el índice vectorial tarde más en compilarse.

      Si no especificas NUM_LISTS, BigQuery calcula un valor apropiado.

    • LEAF_NODE_EMBEDDING_COUNT: un valor INT64 mayor o igual que 500 que especifica la cantidad aproximada de vectores en cada nodo hoja del árbol que crea el algoritmo de TreeAH. El algoritmo de TreeAH divide todo el espacio de datos en una cantidad de listas, y cada lista contiene aproximadamente LEAF_NODE_EMBEDDING_COUNT datos. Un valor más bajo crea más listas con menos datos, mientras que un valor mayor crea menos listas con más datos. El valor predeterminado es 1,000.

    • NORMALIZATION_TYPE: un valor STRING. Los valores admitidos son NONE or L2. El valor predeterminado es NONE. La normalización ocurre antes de cualquier procesamiento, tanto para los datos de la tabla base como para los datos de la consulta, pero no modifica la columna de incorporación COLUMN_NAME en TABLE_NAME. Según el conjunto de datos, el modelo de incorporación y el tipo de distancia que se use durante VECTOR_SEARCH, la normalización de las incorporaciones podría mejorar la recuperación.

En el siguiente ejemplo, se crea un índice vectorial en la columna 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');

En el siguiente ejemplo, se crea un índice vectorial en la columna embedding de my_table y se especifica el tipo de distancia que se usará y las opciones de 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}')

En el siguiente ejemplo, se crea un índice vectorial en la columna embedding de my_table y se especifica el tipo de distancia que se usará y las opciones de 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"}');

Elige un tipo de índice vectorial

BigQuery ofrece dos tipos de índices vectoriales.

Índice de IVF

El IVF es un índice de archivos invertidos que usa un algoritmo k-means para agrupar los datos vectoriales y, luego, particionarlos en función de esos clústeres. Cuando usas la función VECTOR_SEARCH con el objetivo de buscar datos vectoriales, puede usar estas particiones para reducir la cantidad de datos que necesita leer a fin de determinar un resultado.

Índice de TreeAH

TreeAH es un tipo de índice vectorial que usa el algoritmo ScaNN de Google. Esto funciona de la siguiente manera:

  • La tabla base se divide en fragmentos más pequeños y más fáciles de administrar.

  • Se entrena un modelo de agrupamiento en clústeres, con la cantidad de clústeres derivada de la opción leaf_node_embedding_count en tree_ah_options.

  • Los vectores se cuantifican y almacenan en las tablas de índices.

  • Durante VECTOR_SEARCH, una lista de candidatos para cada vector de consulta se calcula de manera eficiente mediante el hash asimétrico, que está optimizado por hardware para los cálculos de distancia aproximada. Luego, se vuelve a calificar a estos candidatos y se los vuelve a clasificar con incorporaciones exactas.

El algoritmo de TreeAH está optimizado para consultas por lotes que procesan cientos o más vectores de consulta. El uso de la cuantización de productos puede reducir de forma significativa la latencia y los costos, potencialmente por órdenes de magnitud en comparación con el IVF. Sin embargo, debido a la mayor sobrecarga, el algoritmo de IVF podría ser mejor cuando tienes una cantidad menor de vectores de consulta.

Te sugerimos que pruebes el tipo de índice de TreeAH si tu caso de uso cumple con los siguientes criterios:

  • Tu tabla contiene 200 millones de filas o menos.

  • Ejecutas consultas por lotes grandes con cientos o más vectores de consulta con frecuencia.

    Para consultas por lotes pequeñas, VECTOR_SEARCH con el tipo de índice TreeAH podría recurrir a la fuerza bruta. En ese caso, se propaga un motivo por el que no se usó el índice vectorial para explicar el motivo.

  • Tu flujo de trabajo no requiere el uso de columnas almacenadas ni filtros previos. BigQuery trata a los filtros previos que se usan con un índice de TreeAH como filtros posteriores.

Si tienes preguntas o inquietudes, en especial sobre la escalabilidad, los límites y el rendimiento, comunícate con nosotros a través de bq-vector-search@google.com.

Almacena columnas y aplica un filtro previo

Para mejorar aún más la eficiencia de tu índice vectorial, puedes especificar columnas de la tabla base para almacenarlas en tu índice vectorial. El uso de columnas almacenadas puede optimizar las consultas que llaman a la función VECTOR_SEARCH de las siguientes maneras:

  • La función VECTOR_SEARCH genera un struct llamado base que contiene todas las columnas de la tabla base. Sin columnas almacenadas, se necesita una unión potencialmente costosa para recuperar las columnas almacenadas en base. Si tu consulta solo selecciona columnas almacenadas de base, BigQuery optimiza tu consulta para eliminar esa unión.

  • En lugar de buscar en una tabla completa, puedes llamar al comando VECTOR_SEARCH en una instrucción de consulta que filtra previamente la tabla base con una cláusula WHERE. Si tu tabla tiene un índice y filtras solo las columnas almacenadas, BigQuery optimiza la consulta. Para ello, filtra los datos antes de la búsqueda y, luego, usa el índice para buscar el conjunto de resultados más pequeño. Si filtras columnas que no están almacenadas, BigQuery aplica el filtro después de que se busca la tabla, o post filtros.

    El filtrado posterior es menos eficiente y puede causar menos de top_k coincidencias en el conjunto de resultados. En algunos casos, el filtrado previo también puede reducir el tamaño del conjunto de resultados. Si esto sucede, intenta aumentar el valor de fraction_lists_to_search en tu llamada a VECTOR_SEARCH.

Para almacenar columnas, enuméralas en la cláusula STORING de la declaración DDL CREATE VECTOR INDEX. El almacenamiento de columnas aumenta el tamaño del índice vectorial, por lo que es mejor almacenar solo las columnas que se usan o filtran con mayor frecuencia.

En el siguiente ejemplo, se crea un índice vectorial con columnas almacenadas y, luego, se explica el comportamiento de los distintos tipos de búsquedas de vectores:

-- 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}');

Limitaciones

  • No puedes usar vistas lógicas en tu filtro previo.
  • Si tu filtro previo contiene una subconsulta, puede interferir en el uso del índice.
  • Si se cambia el modo, el tipo o el esquema de una columna en la tabla base y si es una columna almacenada en el índice vectorial, puede haber una demora antes de que ese cambio se refleje en el índice vectorial. Hasta que se apliquen las actualizaciones al índice, las consultas de búsqueda de vectores usarán las columnas almacenadas modificadas de la tabla base.
  • Si seleccionas una columna de tipo STRUCT del resultado query de una consulta VECTOR_SEARCH en una tabla que tiene un índice con columnas almacenadas, toda la consulta podría fallar.
  • Las columnas almacenadas no son compatibles con los índices de TreeAH.

Comprende la actualización de índices

BigQuery administra completamente los índices vectoriales y los actualizan de forma automática cuando cambia la tabla indexada. Si borras la columna indexada en una tabla o cambias el nombre de la tabla, el índice vectorial se borra de forma automática.

Si creas un índice vectorial en una tabla de menos de 10 MB, el índice vectorial no se propaga. Del mismo modo, si borras datos de una tabla indexada y el tamaño de la tabla es inferior a 10 MB, el índice vectorial se inhabilita temporalmente. En este caso, las consultas de búsqueda vectorial no usan el índice, y el código indexUnusedReasons en la sección vectorSearchStatistics del recurso Job es BASE_TABLE_TOO_SMALL. Sin el índice, VECTOR_SEARCH de forma automática aplica la fuerza bruta para encontrar los vecinos más cercanos de las incorporaciones.

Las consultas que usan la función VECTOR_SEARCH siempre muestran resultados correctos, incluso si alguna parte de los datos aún no está indexada.

Obtén información sobre los índices vectoriales

Puedes verificar la existencia y la preparación de un índice vectorial mediante una consulta a INFORMATION_SCHEMA. Las siguientes vistas contienen metadatos en índices vectoriales:

  • La vista INFORMATION_SCHEMA.VECTOR_INDEXES contiene información sobre los índices vectoriales de un conjunto de datos.

    Una vez que se completa la declaración CREATE VECTOR INDEX, el índice debe propagarse antes de que puedas usarlo. Puedes usar las columnas last_refresh_time y coverage_percentage para verificar la preparación de un índice vectorial. Si el índice vectorial no está listo, puedes usar la función VECTOR_SEARCH en una tabla, que podría ejecutarse más lento sin el índice.

  • La vista INFORMATION_SCHEMA.VECTOR_INDEX_COLUMNS tiene información sobre las columnas indexadas por vector para todas las tablas en un conjunto de datos.

  • La vista INFORMATION_SCHEMA.VECTOR_INDEX_OPTIONS contiene información sobre las opciones que usan los índices vectoriales en un conjunto de datos.

Ejemplos de índices vectoriales

En el siguiente ejemplo, se muestran todos los índices vectoriales activos en las tablas del conjunto de datos my_dataset, ubicado en el proyecto my_project. Incluye los nombres, las declaraciones DDL que se usan para crearlos y el porcentaje de cobertura. Si una tabla base indexada tiene menos de 10 MB, su índice no se propaga. En ese caso, el valor coverage_percentage será 0.

SELECT table_name, index_name, ddl, coverage_percentage
FROM my_project.my_dataset.INFORMATION_SCHEMA.VECTOR_INDEXES
WHERE index_status = 'ACTIVE';

El resultado es similar al siguiente:

+------------+------------+-------------------------------------------------------------------------------------------------+---------------------+
| 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"}') |                     |
+------------+------------+-------------------------------------------------------------------------------------------------+---------------------+

Ejemplos de columnas de índice vectorial

La siguiente consulta extrae información sobre las columnas que tienen índices vectoriales:

SELECT table_name, index_name, index_column_name, index_field_path
FROM my_project.dataset.INFORMATION_SCHEMA.VECTOR_INDEX_COLUMNS;

El resultado es similar al siguiente:

+------------+------------+-------------------+------------------+
| table_name | index_name | index_column_name | index_field_path |
+------------+------------+-------------------+------------------+
| table1     | indexa     | embeddings        | embeddings       |
| table2     | indexb     | vectors           | vectors          |
| table3     | indexc     | vectors           | vectors          |
+------------+------------+-------------------+------------------+

Ejemplos de opciones de índices vectoriales

En la siguiente consulta, se extrae información sobre las opciones de índice vectorial:

SELECT table_name, index_name, option_name, option_type, option_value
FROM my_project.dataset.INFORMATION_SCHEMA.VECTOR_INDEX_OPTIONS;

El resultado es similar al siguiente:

+------------+------------+------------------+------------------+-------------------------------------------------------------------+
| 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"} |
+------------+------------+------------------+------------------+-------------------------------------------------------------------+

Uso del índice vectorial

La información sobre el uso del índice vectorial está disponible en los metadatos del trabajo en el que se ejecutó la consulta de búsqueda vectorial. Puedes ver los metadatos del trabajo mediante la consola de Google Cloud, la herramienta de línea de comandos de bq, la API de BigQuery o las bibliotecas cliente.

Cuando usas la consola de Google Cloud, puedes encontrar información de uso del índice vectorial en los campos Modo de uso del índice vectorial y Motivos por los que no se usó el índice vectorial.

Cuando usas la herramienta de bq o la API de BigQuery, puedes encontrar información de uso del índice vectorial en la sección VectorSearchStatistics del recurso Job.

El modo de uso del índice indica si se usó un índice vectorial cuando se proporciona uno de los siguientes valores:

  • UNUSED: No se usó ningún índice vectorial.
  • PARTIALLY_USED: Algunas funciones VECTOR_SEARCH en la consulta usaron índices vectoriales y otras no.
  • FULLY_USED: Cada función VECTOR_SEARCH en la consulta usó un índice vectorial.

Cuando el valor del modo de uso de índice es UNUSED o PARTIALLY_USED, los motivos por los que no se usó el índice indican por qué no se usaron los índices vectoriales en la consulta.

Por ejemplo, los siguientes resultados que muestra bq show --format=prettyjson -j my_job_id muestran que el índice no se usó porque la opción use_brute_force se especificó en la función 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"
}

Opciones de administración de índices

Para crear índices y hacer que BigQuery los mantenga, tienes dos opciones:

  • Usa el grupo de ranuras compartido predeterminado: Cuando los datos que planeas indexar están por debajo del límite por organización, puedes usar el grupo de ranuras compartido gratuito para la administración de índices.
  • Usa tu propia reserva: para lograr un progreso de indexación más predecible y coherente en tus cargas de trabajo de producción más grandes, puedes usar tus propias reservas para la administración de índices.

Usar ranuras compartidas

Si no configuraste tu proyecto para usar una reserva dedicada para la indexación, la administración de índices se controla en el grupo de ranuras compartido gratuito, sujeto a las siguientes restricciones.

Si agregas datos a una tabla que hace que el tamaño total de las tablas indexadas exceda el límite de tu organización, BigQuery pausa la administración de índices para todas las tablas indexadas. Cuando esto sucede, el campo index_status en la vista INFORMATION_SCHEMA.VECTOR_INDEXES muestra PENDING DISABLEMENT y el índice se pone en cola para su eliminación. Si bien la inhabilitación del índice está pendiente, este se usa en las consultas y se te cobra por el almacenamiento del índice. Después de borrar un índice, el campo index_status muestra el índice como TEMPORARILY DISABLED. En este estado, las consultas no usan el índice y no se te cobra por el almacenamiento de este. En este caso, el código IndexUnusedReason es BASE_TABLE_TOO_LARGE.

Si borras los datos de la tabla y el tamaño total de las tablas indexadas es inferior al límite por organización, la administración de índices se reanuda para todas las tablas indexadas. El campo index_status en la vista INFORMATION_SCHEMA.VECTOR_INDEXES es ACTIVE, las consultas de búsqueda pueden usar el índice de búsqueda y se te cobra por el almacenamiento del índice.

BigQuery no garantiza la capacidad disponible del grupo compartido ni la capacidad de procesamiento de indexación que ves. En aplicaciones de producción, se recomienda usar ranuras dedicadas para el procesamiento de índices.

Usa tu propia reserva

En lugar de usar el grupo de ranuras compartido predeterminado, tienes la opción de designar tu propia reserva para indexar tus tablas. El uso de tu propia reserva garantiza un rendimiento predecible y coherente de los trabajos de administración de índices, como la creación, la actualización y las optimizaciones en segundo plano.

  • No hay límites de tamaño de tabla cuando se ejecuta un trabajo de indexación en tu reserva.
  • El uso de tu propia reserva te brinda flexibilidad en la administración de índices. Si necesitas crear un índice muy grande o aplicar una actualización importante a una tabla indexada, puedes agregar más ranuras a la asignación de forma temporal.

Para indexar las tablas en un proyecto con una reserva designada, crea una reserva en la región en la que se encuentran las tablas. Luego, asigna el proyecto a la reserva con job_type configurado como BACKGROUND:

SQL

Usa la declaración DDL CREATE ASSIGNMENT.

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. En el editor de consultas, escribe la siguiente oración:

    CREATE ASSIGNMENT
      `ADMIN_PROJECT_ID.region-LOCATION.RESERVATION_NAME.ASSIGNMENT_ID`
    OPTIONS (
      assignee = 'projects/PROJECT_ID',
      job_type = 'BACKGROUND');

    Reemplaza lo siguiente:

    • ADMIN_PROJECT_ID por el ID del proyecto de administración que posee el recurso de reserva
    • LOCATION: la ubicación de la reserva
    • RESERVATION_NAME por el nombre de la reserva
    • ASSIGNMENT_ID por el ID de la asignación

      El ID debe ser único para el proyecto y la ubicación, debe empezar y terminar con una letra minúscula o un número y contener solo letras en minúscula, números y guiones.

    • PROJECT_ID: el ID del proyecto que contiene las tablas que se indexarán. Este proyecto está asignado a la reserva.

  3. Haz clic en Ejecutar.

Si deseas obtener información sobre cómo ejecutar consultas, visita Ejecuta una consulta interactiva.

bq

Usa el comando 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

Reemplaza lo siguiente:

  • ADMIN_PROJECT_ID por el ID del proyecto de administración que posee el recurso de reserva
  • LOCATION: la ubicación de la reserva
  • RESERVATION_NAME por el nombre de la reserva
  • PROJECT_ID por el ID del proyecto que se asignará a esta reserva

Ve tus trabajos de indexación

Se crea un trabajo de indexación nuevo cada vez que se crea o se actualiza un índice en una sola tabla. Para ver información sobre el trabajo, consulta las vistas de INFORMATION_SCHEMA.JOBS*. Puedes filtrar los trabajos de indexación si configuras job_type IS NULL AND SEARCH(job_id, '`search_index`') en la cláusula WHERE de tu consulta. En el siguiente ejemplo, se enumeran los cinco trabajos de indexación más recientes en el proyecto 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;

Elige el tamaño de tu reserva

Para elegir la cantidad correcta de ranuras para tu reserva, debes considerar cuándo se ejecutan los trabajos de administración de índices, cuántas ranuras usan y cómo se ve tu uso en el tiempo. BigQuery activa un trabajo de administración de índices en las siguientes situaciones:

  • Debes crear un índice en una tabla.
  • Los datos se modifican en una tabla indexada.
  • El esquema de una tabla cambia y esto afecta qué columnas se indexan.
  • Los datos y metadatos del índice se optimizan o actualizan de forma periódica.

La cantidad de ranuras que necesitas para un trabajo de administración de índices en una tabla depende de los siguientes factores:

  • El tamaño de la tabla
  • La frecuencia de la transferencia de datos a la tabla
  • La tasa de declaraciones DML que se aplican a la tabla
  • El retraso aceptable para compilar y mantener el índice
  • La complejidad del índice, que por lo general se determina según los atributos de los datos, como la cantidad de términos duplicados
Supervisa el uso y el progreso

La mejor manera de evaluar la cantidad de ranuras que necesitas para ejecutar los trabajos de administración de índices de forma eficiente es supervisar el uso de las ranuras y ajustar el tamaño de reserva según corresponda. La siguiente consulta produce el uso diario de las ranuras para los trabajos de administración de índices. Solo se incluyen los últimos 30 días en la región 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;

Cuando no hay suficientes ranuras para ejecutar trabajos de administración de índices, un índice puede dejar de sincronizarse con su tabla y los trabajos de indexación pueden fallar. En este caso, BigQuery vuelve a compilar el índice desde cero. Para evitar tener un índice fuera de sincronización, asegúrate de tener suficientes ranuras para admitir actualizaciones de índice desde la transferencia y optimización de datos. Para obtener más información sobre la supervisión del uso de ranuras, consulta los gráficos de recursos de administrador.

Borra un índice vectorial

Cuando ya no necesites un índice vectorial o quieras cambiar qué columna se indexa en una tabla, puedes borrar el índice de esa tabla mediante la sentencia DDL DROP VECTOR INDEX.

Por ejemplo:

DROP VECTOR INDEX my_index ON my_dataset.indexed_table;

Si se borra una tabla indexada, el índice se borra de forma automática.

¿Qué sigue?