Administra índices vectoriales
En este documento, se describe cómo crear y administrar índices vectoriales para acelerar tus búsquedas de vectores.
Un índice de vectores es una estructura de datos diseñada para permitir que la función VECTOR_SEARCH y la función AI.SEARCH se ejecuten de manera más eficiente, en especial en conjuntos de datos grandes.
Cuando se usa un índice, estas funciones de búsqueda usan algoritmos de
vecino más cercano aproximado (ANN)
para reducir la latencia de las consultas y el costo de procesamiento. Si bien ANN introduce
un grado de aproximación, lo que significa que
la recuperación
podría no ser del 100%, las mejoras de rendimiento suelen ofrecer una ventaja
para la mayoría de las aplicaciones.
Roles 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)
Elige un tipo de índice vectorial
BigQuery ofrece dos tipos de índices vectoriales, IVF y
TreeAH, cada uno de los cuales admite
diferentes casos de uso. BigQuery admite el procesamiento por lotes para la búsqueda de vectores
procesando varias filas de los datos de entrada en la
VECTOR_SEARCH.
Para lotes de consultas pequeños, se prefieren los índices IVF. Para los lotes de consultas grandes, se prefieren los índices TreeAH, que se compilan con el algoritmo ScaNN de Google.
Í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. Las funciones VECTOR_SEARCH y AI.SEARCH pueden usar estas particiones para reducir la cantidad de datos que necesitan leer para determinar un resultado.
Índice de TreeAH
El tipo de índice TreeAH se llama así por su combinación de una estructura similar a un árbol y su uso de hash asimétrico (AH), una técnica de cuantificación central del algoritmo ScaNN subyacente. Un índice de TreeAH 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_counten el argumentotree_ah_optionsde la instrucciónCREATE VECTOR INDEX. - Los vectores se comprimen con la cuantización de productos, una técnica que reduce su uso de memoria. Luego, los vectores comprimidos se almacenan en las tablas de índices en lugar de los vectores originales, lo que reduce los tamaños de los índices de vectores.
- Cuando se ejecuta la función
VECTOR_SEARCHoAI.SEARCH, se calcula de manera eficiente una lista de candidatos para cada vector de consulta con un 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 las consultas por lotes pequeñas con el tipo de índice TreeAH, VECTOR_SEARCH o AI.SEARCH podrían revertirse a la búsqueda de fuerza bruta.
Cuando esto sucede, se proporciona un
IndexUnusedReason
para explicar por qué no se usó el índice vectorial.
Crea un índice vectorial de IVF
Para crear un índice vectorial de IVF, usa la
declaración de lenguaje de definición de datos (DDL) CREATE VECTOR INDEX:
Ve a la página de BigQuery.
En el editor de consultas, ejecuta la siguiente instrucción 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}')
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 deARRAY<FLOAT64>o, si usas la generación de embeddings autónomos, un tipo deSTRUCT<result ARRAY<FLOAT64>, status STRING>.En todos los casos, todos los elementos del array de incorporación deben ser distintos de
NULLy todos los valores de la columna deben tener las mismas dimensiones de array.Si el tipo de columna es
STRUCT<result ARRAY<FLOAT64>, status STRING>, el valor deSTRUCTpuede serNULLo el array deresultpuede serNULL. Se ignoran las filas conNULLpara estos valores.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 de vectores con este índice. Los valores admitidos sonEUCLIDEAN,COSINEyDOT_PRODUCT.EUCLIDEANes la configuración predeterminada.La creación del índice siempre usa la distancia
EUCLIDEANpara el entrenamiento, pero la distancia que se usa en la función de búsqueda puede ser diferente.Si especificas un valor para el argumento
distance_typede la funciónVECTOR_SEARCHoAI.SEARCH, se usa ese valor en lugar del valorDISTANCE_TYPE.NUM_LISTS: un valorINT64que especifica la cantidad de listas en las que el índice de IVF agrupa y, luego, particiona tus datos vectoriales. Este valor debe ser de 5,000 o menos. Durante la indexación, los vectores se asignan a la lista correspondiente a su centroide de clúster más cercano. Si omites este argumento, BigQuery determina un valor predeterminado según las características de tus datos. El valor predeterminado funciona bien para la mayoría de los casos de uso.NUM_LISTScontrola el nivel de detalle del ajuste de consultas. Los valores más altos crean más listas, por lo que puedes configurar la opciónfraction_lists_to_searchde tu función de búsqueda para analizar un porcentaje menor del índice. Por ejemplo, analizar el 1% de 100 listas en lugar del 10% de 10 listas. Esto permite un control más preciso de la velocidad y la recuperación de la búsqueda, pero aumenta ligeramente el costo de indexación. Establece este valor de argumento según la precisión con la que necesites ajustar el alcance de la consulta.
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 una tabla con
la generación autónoma de embeddings
habilitada y se crea un índice vectorial en la tabla. La columna de incorporación de description_embedding se genera automáticamente en función de la columna de description.
CREATE TABLE mydataset.products ( description STRING, description_embedding STRUCT<result ARRAY<FLOAT64>, status STRING> GENERATED ALWAYS AS ( AI.EMBED(description, connection_id => 'us.example_connection', endpoint => 'text-embedding-005')) STORED OPTIONS( asynchronous = TRUE )); CREATE VECTOR INDEX my_index ON my_dataset.my_table(description_embedding) OPTIONS(index_type = 'IVF');
Crea un índice vectorial de TreeAH
Para crear un índice vectorial de TreeAH, usa la declaración del lenguaje de definición de datos (DDL) CREATE VECTOR INDEX:
Ve a la página de BigQuery.
En el editor de consultas, ejecuta la siguiente instrucción de SQL:
CREATE [ OR REPLACE ] VECTOR INDEX [ IF NOT EXISTS ] INDEX_NAME ON DATASET_NAME.TABLE_NAME(COLUMN_NAME) STORING(STORED_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"}')
Reemplaza lo siguiente:
INDEX_NAME: Es el nombre del índice vectorial que estás creando. 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 deARRAY<FLOAT64>o, si usas la generación de embeddings autónomos, un tipo deSTRUCT<result ARRAY<FLOAT64>, status STRING>.En todos los casos, todos los elementos del array de incorporación deben ser distintos de
NULLy todos los valores de la columna deben tener las mismas dimensiones de array. La dimensión del array debe ser de al menos 2.Si el tipo de columna es
STRUCT<result ARRAY<FLOAT64>, status STRING>, el valorSTRUCTpuede serNULLo el arrayresultpuede serNULL. Se ignoran las filas conNULLpara estos valores.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: Es un argumento opcional que especifica el tipo de distancia predeterminado que se usará cuando se realice una búsqueda vectorial con este índice. Los valores admitidos sonEUCLIDEAN,COSINEyDOT_PRODUCT.EUCLIDEANes la configuración predeterminada.La creación del índice siempre usa la distancia
EUCLIDEANpara el entrenamiento, pero la distancia que se usa en la función de búsqueda puede ser diferente.Si especificas un valor para el argumento
distance_typede la funciónVECTOR_SEARCHoAI.SEARCH, se usa ese valor en lugar del valorDISTANCE_TYPE.LEAF_NODE_EMBEDDING_COUNT: un valorINT64mayor 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 aproximadamenteLEAF_NODE_EMBEDDING_COUNTdatos. 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, que es adecuado para la mayoría de los conjuntos de datos.NORMALIZATION_TYPE: un valorSTRING. Los valores admitidos sonNONEoL2. El valor predeterminado esNONE. 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ónCOLUMN_NAMEenTABLE_NAME. Según el conjunto de datos, el modelo de incorporación y el tipo de distancia que se use durante la búsqueda, 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 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"}');
Usa índices de vectores con la búsqueda híbrida
Para mejorar el rendimiento de las búsquedas de búsqueda híbrida, puedes agregar la información de palabras clave necesaria para procesar una búsqueda léxica a tu índice de vectores especificando lexical_search_columns en tu instrucción CREATE VECTOR INDEX. Esto se puede hacer para cualquier tipo de índice vectorial existente,
como IVF o TreeAH. La siguiente sentencia CREATE VECTOR INDEX de ejemplo incluye información de palabras clave. En este ejemplo, la opción lexical_search_columns enumera todas las columnas que se usan para la parte léxica de una búsqueda híbrida. Cualquier columna que se agregue a la lista
lexical_search_columns también se debe agregar como una columna almacenada en la
cláusula STORING:
CREATE [ OR REPLACE ] VECTOR INDEX [ IF NOT EXISTS ] INDEX_NAME ON DATASET_NAME.TABLE_NAME(COLUMN_NAME) STORING(STORED_COLUMN_NAME [, ...]) OPTIONS( index_type = 'INDEX_TYPE', distance_type = 'DISTANCE_TYPE', ivf_options = '{"num_lists":NUM_LISTS}' lexical_search_columns = [LEXICAL_COLUMN_NAME [, ...]])
En el siguiente ejemplo de búsqueda híbrida,
se crea un índice vectorial en la columna de embeddings de my_table. Las
columnas header, content y footer se usan para la búsqueda léxica en las consultas de búsqueda
híbrida:
CREATE VECTOR INDEX `hybrid_index` ON `my_dataset.my_table`(`embedding`) STORING(`header`, `content`, `footer`) OPTIONS ( index_type = 'IVF', distance_type = 'EUCLIDEAN', lexical_search_columns = ['header', 'content', 'footer']);
Filtros
En las siguientes secciones, se explica cómo los filtros previos y posteriores afectan los resultados de la búsqueda de vectores y cómo aplicar un filtro previo con columnas y particiones almacenadas en el índice de vectores.
Prefiltrado y filtrado posterior
En las llamadas a VECTOR_SEARCH o AI.SEARCH de BigQuery, tanto el prefiltrado como el filtrado posterior sirven para refinar los resultados de la búsqueda, ya que aplican condiciones basadas en las columnas de metadatos asociadas con los embeddings de vectores. Es importante
comprender sus diferencias, implementación y repercusión para optimizar
el rendimiento, el costo y la exactitud de las consultas.
El prefiltrado y el filtrado posterior se definen de la siguiente manera:
- Filtrado previo: Aplica condiciones de filtro antes de que la búsqueda de vecino más cercano aproximado (ANN) realice cálculos de distancia en los vectores candidatos. Esto reduce el conjunto de vectores que se consideran durante la búsqueda. En consecuencia, el filtrado previo suele generar tiempos de consulta más rápidos y un costo de procesamiento reducido, ya que la búsqueda de ANN evalúa menos candidatos potenciales.
- Filtrado posterior: Aplica condiciones de filtro después de que la búsqueda de ANN
identifica los vecinos más cercanos de
top_kiniciales. Esto refina el conjunto de resultados final según los criterios especificados.
La ubicación de la cláusula WHERE determina si un filtro actúa como un prefiltrado o un filtrado posterior.
Para crear un prefiltrado, la cláusula WHERE de la consulta debe aplicarse al argumento de la tabla base de la función de búsqueda. Para que el filtrado previo reduzca los datos y
optimice la búsqueda de índices, el predicado debe aplicarse a una
columna almacenada o a una columna de partición. Si el predicado se aplica a cualquier otra columna, incluida una columna agrupada no almacenada, actúa como un filtro posterior y genera un análisis completo.
En el siguiente ejemplo, se muestra cómo crear un prefiltro:
-- 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); SELECT * FROM AI.SEARCH( (SELECT * FROM my_dataset.my_table WHERE type = 'animal'), 'content', 'dog'); -- 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 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}');
Para crear un filtro posterior, la cláusula WHERE de la consulta debe aplicarse fuera de la función VECTOR_SEARCH, de modo que filtre los resultados que devuelve la búsqueda.
En el siguiente ejemplo, se muestra cómo crear un filtro posterior:
-- 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'; SELECT base.id, distance FROM VECTOR_SEARCH( TABLE mydataset.base_table, 'embedding', (SELECT embedding FROM mydataset.query_table), top_k => 10 ) WHERE type = 'document' AND year > 2022
Cuando usas el filtrado posterior o cuando los filtros de la tabla base que especificas hacen referencia a columnas no almacenadas y, por lo tanto, actúan como filtros posteriores, el conjunto de resultados final puede contener menos de top_k filas, incluso ninguna, si el predicado es selectivo. Si necesitas una cantidad específica de resultados después de aplicar el filtro, considera especificar un valor top_k más grande o aumentar el valor fraction_lists_to_search en la llamada a la función de búsqueda.
En algunos casos, en especial si el filtro previo es muy selectivo, 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 la llamada a la función de búsqueda.
Prefiltrado con columnas almacenadas
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 las funciones VECTOR_SEARCH o AI.SEARCH de las siguientes maneras:
En lugar de buscar en una tabla completa, puedes llamar a una función de búsqueda en una instrucción de consulta que prefiltra 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 filtrado posterior.Las funciones
VECTOR_SEARCHyAI.SEARCHgeneran un struct llamadobaseque contiene todas las columnas de la tabla base. Sin columnas almacenadas, se necesita una unión potencialmente costosa para recuperar las columnas almacenadas enbase. Si usas un índice de IVF y tu consulta solo selecciona columnas almacenadas debase, BigQuery optimiza tu consulta para eliminar esa unión. En el caso de los índices de TreeAH, no se quita la unión con la tabla base. Las columnas almacenadas en los índices de TreeAH solo se usan para fines de prefiltrado.
Para almacenar columnas, enuméralas en la cláusula STORING de la
declaración 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 ejecuta una consulta de búsqueda de vectores que solo selecciona columnas almacenadas:
-- 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);
Limitaciones de las columnas almacenadas
- 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
STRUCTdel resultadoqueryde una búsqueda en una tabla que tiene un índice con columnas almacenadas, toda la búsqueda podría fallar.
Prefiltrado con particiones
Si la tabla en la que creas el índice vectorial está particionada, también puedes elegir particionar el índice vectorial. La partición del índice de vectores tiene los siguientes beneficios:
- La reducción de particiones se aplica a los índices de vectores, además de a las particiones de la tabla. La reducción de particiones se produce cuando la búsqueda de vectores usa un filtro apto en el valor de la columna de partición. Esto permite que BigQuery analice las particiones que coinciden con el filtro y omita las restantes. La eliminación de particiones puede reducir los costos de E/S. Para obtener más información sobre la reducción de particiones, consulta Consulta tablas particionadas.
- Es menos probable que la búsqueda vectorial omita resultados si aplicas un filtro previo en la columna de partición.
Solo puedes particionar los índices de vectores de TreeAH. No puedes crear un índice de vectores particionado en una columna de embeddings generada automáticamente.
Solo se recomienda particionar un índice de vectores si usas el filtrado previo para limitar la mayoría de tus búsquedas de vectores a unas pocas particiones.
Para crear un índice particionado, usa la cláusula PARTITION BY de la
declaración CREATE VECTOR INDEX. La cláusula PARTITION BY que especificas en la instrucción CREATE VECTOR INDEX debe ser la misma que la cláusula PARTITION BY especificada en la instrucción CREATE TABLE de la tabla en la que creas el índice vectorial, como se muestra en el siguiente ejemplo:
-- Create a date-partitioned table. CREATE TABLE my_dataset.my_table( embeddings ARRAY, id INT64, date DATE, ) PARTITION BY date; -- Create a partitioned vector index on the table. CREATE VECTOR INDEX my_index ON my_dataset.my_table(embeddings) PARTITION BY date OPTIONS(index_type='TREE_AH', distance_type='COSINE');
Si la tabla usa la partición de columna de unidad de tiempo o rango de números enteros, la columna de partición se almacena en el índice vectorial, lo que aumenta el costo de almacenamiento.
Si se usa una columna de tabla en las cláusulas STORING y PARTITION BY de
la declaración CREATE VECTOR INDEX, la columna se almacena solo una vez.
Para usar la partición del índice vectorial, filtra por la columna de partición en la
subconsulta de la tabla base de la llamada a VECTOR_SEARCH o AI.SEARCH.
En el siguiente ejemplo,
la tabla samples.items se particiona por la columna produced_date,
por lo que la subconsulta de la tabla base en la sentencia VECTOR_SEARCH filtra por la
columna produced_date:
SELECT query.id, base.id, distance FROM VECTOR_SEARCH( (SELECT * FROM my_dataset.my_table WHERE produced_date = '2025-01-01'), 'embedding', TABLE samples.test, distance_type => 'COSINE', top_k => 10 );
Ejemplos
Crea un índice vectorial particionado en una tabla particionada por fecha y hora:
-- Create a datetime-partitioned table. CREATE TABLE my_dataset.my_table( id INT64, produced_date DATETIME, embeddings ARRAY) PARTITION BY produced_date; -- Create a partitioned vector index on the table. CREATE VECTOR INDEX index0 ON my_dataset.my_table(embeddings) PARTITION BY produced_date OPTIONS(index_type='TREE_AH', distance_type='COSINE');
Crea un índice vectorial particionado en una tabla particionada por marcas de tiempo:
-- Create a timestamp-partitioned table. CREATE TABLE my_dataset.my_table( id INT64, produced_time TIMESTAMP, embeddings ARRAY) PARTITION BY TIMESTAMP_TRUNC(produced_time, HOUR); -- Create a partitioned vector index on the table. CREATE VECTOR INDEX index0 ON my_dataset.my_table(embeddings) PARTITION BY TIMESTAMP_TRUNC(produced_time, HOUR) OPTIONS(index_type='TREE_AH', distance_type='COSINE');
Crea un índice vectorial particionado en una tabla particionada por rango de números enteros:
-- Create an integer range-partitioned table. CREATE TABLE my_dataset.my_table( id INT64, embeddings ARRAY) PARTITION BY RANGE_BUCKET(id, GENERATE_ARRAY(-100, 100, 20)); -- Create a partitioned vector index on the table. CREATE VECTOR INDEX index0 ON my_dataset.my_table(embeddings) PARTITION BY RANGE_BUCKET(id, GENERATE_ARRAY(-100, 100, 20)) OPTIONS(index_type='TREE_AH', distance_type='COSINE');
Crea un índice vectorial particionado en una tabla particionada por tiempo de transferencia:
-- Create an ingestion time-partitioned table. CREATE TABLE my_dataset.my_table( id INT64, embeddings ARRAY) PARTITION BY TIMESTAMP_TRUNC(_PARTITIONTIME, DAY); -- Create a partitioned vector index on the table. CREATE VECTOR INDEX index0 ON my_dataset.my_table(embeddings) PARTITION BY TIMESTAMP_TRUNC(_PARTITIONTIME, DAY) OPTIONS(index_type='TREE_AH', distance_type='COSINE');
Limitaciones del filtrado previo
- No puedes usar vistas lógicas en tu filtro previo.
- Si tu filtro previo contiene una subconsulta, puede interferir en el uso del índice.
- La eliminación de datos con filtrado previo solo se optimiza cuando se filtra en columnas particionadas o columnas almacenadas, no en columnas agrupadas en clústeres.
Cuándo se indexan los datos
BigQuery administra completamente los índices vectoriales y los actualiza de forma automática cuando cambia la tabla indexada.
La indexación es asíncrona. Hay un retraso entre el momento en que se agregan filas nuevas a la tabla base y el momento en que se reflejan en el índice. Sin embargo, las funciones VECTOR_SEARCH y AI.SEARCH aún tienen en cuenta todas las filas y no omiten las filas sin indexar. Las funciones buscan con el índice los registros indexados y usan la búsqueda de fuerza bruta para los registros que aún no están indexados.
Si creas un índice vectorial en una columna de incorporación generada automáticamente, el entrenamiento del índice comienza en cuanto al menos el 80% de las filas tienen incorporaciones generadas.
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 de vectores 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,
la función de búsqueda recurre automáticamente a la fuerza bruta para encontrar los
vecinos más cercanos de las incorporaciones.
Si borras la columna indexada en una tabla o cambias el nombre de la tabla, el índice vectorial se borra de forma automática.
Supervisa el estado de los índices vectoriales
Puedes supervisar el estado de tus índices vectoriales consultando
las vistas INFORMATION_SCHEMA. Las siguientes vistas contienen metadatos en índices vectoriales:
La vista
INFORMATION_SCHEMA.VECTOR_INDEXEScontiene 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 columnaslast_refresh_timeycoverage_percentagepara verificar la preparación de un índice vectorial. Si el índice vectorial no está listo, puedes usar las funcionesVECTOR_SEARCHyAI.SEARCHen una tabla, que podrían ejecutarse más lento sin el índice.La vista
INFORMATION_SCHEMA.VECTOR_INDEX_COLUMNStiene información sobre las columnas indexadas por vector para todas las tablas en un conjunto de datos.La vista
INFORMATION_SCHEMA.VECTOR_INDEX_OPTIONScontiene 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"} |
+------------+------------+------------------+------------------+-------------------------------------------------------------------+
Verifica el 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 con 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 de búsqueda en la consulta usaron índices vectoriales y otras no.FULLY_USED: Cada función de búsqueda 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"
}
Problema conocido: El uso del índice vectorial puede ser impreciso cuando la consulta se está ejecutando, se cancela o falla.
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 esa tabla. 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 el í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, se reanudará la administración de índices. 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.
Puedes usar la vista INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION para comprender tu consumo actual en relación con el límite por organización en una región determinada, desglosado por proyectos y tablas.
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, que comparte recursos entre los trabajos de optimización en segundo plano:
SQL
Usa la declaración DDL CREATE ASSIGNMENT.
En la consola de Google Cloud , ve a la página BigQuery.
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_IDpor el ID del proyecto de administración que posee el recurso de reservaLOCATION: la ubicación de la reservaRESERVATION_NAMEpor el nombre de la reservaASSIGNMENT_IDpor el ID de la asignaciónEl 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.
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_IDpor el ID del proyecto del proyecto de administración que posee el recurso de reservaLOCATION: la ubicación de la reservaRESERVATION_NAMEpor el nombre de la reservaPROJECT_IDpor 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 sentencias 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 de datos y la optimización. Para obtener más información sobre la supervisión del uso de ranuras, consulta los gráficos de recursos de administrador.
Vuelve a compilar un índice vectorial
Cuando los datos de la tabla cambian de forma significativa después de crear un índice vectorial, este puede volverse menos eficiente. Cuando un índice vectorial es menos eficiente, una consulta de búsqueda de vectores que inicialmente tenía una alta recuperación cuando se usa el índice tendrá una recuperación más baja, ya que el cambio de distribución de datos en la tabla base no se representa en el índice vectorial.
Si deseas mejorar la recuperación sin aumentar la latencia de la consulta de búsqueda, vuelve a compilar
el índice de vectores. Como alternativa, puedes aumentar el valor de la opción fraction_lists_to_search de la búsqueda de vectores para mejorar la recuperación, pero esto suele ralentizar la búsqueda. Para saber cuándo se compiló un índice por última vez, ejecuta la siguiente consulta:
SELECT last_model_build_time FROM DATASET_NAME.INFORMATION_SCHEMA.VECTOR_INDEXES WHERE table_name = TABLE_NAME;
Puedes usar la función VECTOR_INDEX.STATISTICS para calcular cuánto se han desviado los datos de una tabla indexada desde que se creó un índice de vectores hasta el presente.
Si los datos de la tabla cambiaron lo suficiente como para requerir una reconstrucción del índice vectorial, puedes usar
la sentencia ALTER VECTOR INDEX REBUILD
para reconstruir el índice vectorial sin tener que descartarlo y sin
tiempo de inactividad del índice. Cuando ejecutas la sentencia, BigQuery crea
un índice de sombra, un índice solo en segundo plano que hereda la configuración del
índice actual, en la tabla y lo entrena en segundo plano.
BigQuery promueve el índice secundario para que sea el índice activo cuando tiene suficiente cobertura.
Sigue estos pasos para volver a compilar un índice de vectores:
Ve a la página de BigQuery.
En el editor de consultas, ejecuta la siguiente instrucción de SQL para verificar la desviación de los datos de la tabla indexada:
SELECT * FROM VECTOR_INDEX.STATISTICS(TABLE DATASET_NAME.TABLE_NAME);
Reemplaza lo siguiente:
DATASET_NAME: Es el nombre del conjunto de datos que contiene la tabla indexada.TABLE_NAME: Es el nombre de la tabla que contiene el índice de vectores.
La función devuelve un valor
FLOAT64en el rango[0,1). Un valor más bajo indica menos desvío. Por lo general, un valor de0.3o más se considera un cambio lo suficientemente significativo como para indicar que una reconstrucción del índice de vectores podría ser beneficiosa.Si la función
VECTOR_INDEX.STATISTICSindica que la desviación de los datos de la tabla es significativa, ejecuta la siguiente instrucción de SQL para volver a compilar el índice de vectores:ALTER VECTOR INDEX IF EXISTS INDEX_NAME ON DATASET_NAME.TABLE_NAME REBUILD;
Reemplaza lo siguiente:
INDEX_NAME: Es el nombre del índice vectorial que estás recompilando.DATASET_NAME: Es el nombre del conjunto de datos que contiene la tabla indexada.TABLE_NAME: Es el nombre de la tabla que contiene el índice vectorial.
Supervisa una reconstrucción
Para supervisar la recompilación del índice, consulta la vista INFORMATION_SCHEMA.VECTOR_INDEXES.
Por ejemplo, en la siguiente consulta, se muestra el estado de reconstrucción de todos los índices de las tablas del conjunto de datos my_dataset en el proyecto my_project. Si un índice
no tiene una reconstrucción en curso, el valor de last_index_alteration_info es
NULL.
SELECT
table_name,
index_name,
last_index_alteration_info.status AS status,
last_index_alteration_info.new_coverage_percentage AS coverage
FROM my_project.my_dataset.INFORMATION_SCHEMA.VECTOR_INDEXES
El resultado es similar al siguiente:
+------------+------------+-------------+----------+
| table_name | index_name | status | coverage |
+------------+------------+-------------+----------+
| table1 | index_a | IN_PROGRESS | 50 |
| table2 | index_b | null | null |
+------------+------------+-------------+----------+
Cancela una reconstrucción
Para cancelar la reconstrucción de un índice de vectores, usa el
procedimiento del sistema BQ.CANCEL_INDEX_ALTERATION.
Es posible que una operación de alteración de índice se complete antes de que se procese la solicitud de
cancelación. Para confirmar si la operación se canceló de forma correcta, consulta
la
vista INFORMATION_SCHEMA.VECTOR_INDEXES.
Si la cancelación se realizó correctamente, el campo last_model_build_time no se actualiza y el campo last_index_alteration_info no está presente para ese índice.
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 con la
sentencia DDL DROP VECTOR INDEX:
Ve a la página de BigQuery.
En el editor de consultas, ejecuta la siguiente instrucción de SQL:
DROP VECTOR INDEX INDEX_NAME ON DATASET_NAME.TABLE_NAME;
Reemplaza lo siguiente:
INDEX_NAME: Es el nombre del índice vectorial que borras.DATASET_NAME: Es el nombre del conjunto de datos que contiene la tabla indexada.TABLE_NAME: Es el nombre de la tabla que contiene el índice vectorial.
Si se borra una tabla indexada, el índice se borra de forma automática.
Exporta embeddings a Vector Search
Para habilitar aplicaciones en línea de latencia ultrabaja, usa la integración de BigQuery con la Vector Search de Gemini Enterprise Agent Platform para importar tus embeddings de BigQuery a Vector Search y, luego, implementar extremos de baja latencia. Para obtener más información, consulta Importa datos de índice desde BigQuery.
¿Qué sigue?
- Para obtener una descripción general de los casos de uso de índices vectoriales, los precios y las limitaciones, consulta la Introducción a la búsqueda vectorial.
- Aprende a realizar una búsqueda vectorial con la
función
VECTOR_SEARCH. - Aprende a realizar una búsqueda semántica con la
función
AI.SEARCH. - Obtén más información sobre la
declaración
CREATE VECTOR INDEX. - Prueba el instructivo Busca embeddings con Vector Search.