En esta página se explica cómo crear y gestionar índices vectoriales de Spanner, que usan la búsqueda del vecino más cercano aproximado (ANN) y estructuras basadas en árboles para acelerar las búsquedas de similitud vectorial en tus datos.
Spanner acelera las búsquedas vectoriales de vecinos más cercanos aproximados (ANN) mediante un índice vectorial especializado. Este índice aprovecha la búsqueda de vecinos más cercanos escalable (ScaNN) de Google Research, un algoritmo de vecinos más cercanos muy eficiente.
El índice vectorial usa una estructura basada en árbol para particionar los datos y facilitar las búsquedas. Spanner ofrece configuraciones de árbol de dos y tres niveles:
- Configuración de árbol de dos niveles: los nodos hoja (
num_leaves
) contienen grupos de vectores estrechamente relacionados junto con su centroide correspondiente. El nivel raíz está formado por los centroides de todos los nodos hoja. - Configuración de árbol de tres niveles: similar al concepto de árbol de dos niveles, pero con una capa de rama adicional (
num_branches
) desde la que se particionan los centroides de los nodos hoja para formar el nivel raíz (num_leaves
).
Spanner elige un índice por ti. Sin embargo, si sabes que un índice específico funciona mejor, puedes usar la FORCE_INDEX
pista
para elegir el índice vectorial más adecuado para tu caso práctico.
Para obtener más información, consulta las VECTOR INDEX
declaraciones.
Limitaciones
- No puedes dividir previamente los índices vectoriales. Para obtener más información, consulta la introducción a la prepartición.
Crear un índice vectorial
Para optimizar la recuperación y el rendimiento de un índice vectorial, te recomendamos que hagas lo siguiente:
Crea el índice vectorial después de que se hayan escrito en tu base de datos la mayoría de las filas con incrustaciones. También es posible que tengas que volver a compilar periódicamente el índice vectorial después de insertar datos nuevos. Para obtener más información, consulta Reconstruir el índice vectorial.
Usa la cláusula
STORING
para almacenar una copia de una columna en el índice vectorial. Si un valor de columna se almacena en el índice vectorial, Spanner realiza el filtrado a nivel de hoja del índice para mejorar el rendimiento de las consultas. Te recomendamos que almacenes una columna si se usa en una condición de filtrado. Para obtener más información sobre cómo usarSTORING
en un índice, consulta el artículo Crear un índice para análisis solo de índice.
Cuando cree la tabla, la columna de inserción debe ser una matriz del tipo de datos FLOAT32
(recomendado) o FLOAT64
, y tener una anotación vector_length que indique la dimensión de los vectores.
La siguiente instrucción DDL crea una tabla Documents
con una columna de inserción DocEmbedding
con una longitud de vector:
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING (1024),
DocContents Bytes(MAX),
DocEmbedding ARRAY<FLOAT32>(vector_length=>128) NOT NULL,
NullableDocEmbedding ARRAY<FLOAT32>(vector_length=>128),
WordCount INT64,
) PRIMARY KEY (DocId);
Una vez que hayas rellenado la tabla Documents
, puedes crear un índice vectorial con un árbol de dos niveles y 1000 nodos hoja en la tabla Documents
con una columna de inserciones DocEmbedding
usando la distancia del coseno:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(DocEmbedding)
STORING (WordCount)
OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);
Si la columna de inserciones no está marcada como NOT NULL
en la definición de la tabla, debes declararla con una cláusula WHERE COLUMN_NAME IS NOT NULL
en la definición del índice vectorial, donde COLUMN_NAME
es el nombre de la columna de inserciones. Para crear un índice vectorial con un árbol de tres niveles y 1.000.000 de nodos hoja en la columna de incrustación anulable NullableDocEmbedding
con la distancia del coseno, sigue estos pasos:
CREATE VECTOR INDEX DocEmbeddingThreeLevelIndex
ON Documents(NullableDocEmbedding)
STORING (WordCount)
WHERE NullableDocEmbedding IS NOT NULL
OPTIONS (distance_type = 'COSINE', tree_depth = 3, num_branches=1000, num_leaves = 1000000);
Filtrar un índice de vectores
También puede crear un índice vectorial filtrado para encontrar los elementos más similares de su base de datos que cumplan la condición del filtro. Un índice de vectores filtrado indexa de forma selectiva las filas que cumplen las condiciones de filtro especificadas, lo que mejora el rendimiento de la búsqueda.
En el ejemplo siguiente, la tabla Documents2
tiene una columna llamada Category
.
En nuestra búsqueda vectorial, queremos indexar la categoría "Tecnología", por lo que creamos una columna generada que se evalúa como NULL
si no se cumple la condición de la categoría.
CREATE TABLE Documents2 (
DocId INT64 NOT NULL,
Category STRING(MAX),
NullIfFiltered BOOL AS (IF(Category = 'Tech', TRUE, NULL)) HIDDEN,
DocEmbedding ARRAY<FLOAT32>(vector_length=>128),
) PRIMARY KEY (DocId);
Después, creamos un índice vectorial con un filtro. El índice vectorial TechDocEmbeddingIndex
solo indexa documentos de la categoría "Tecnología".
CREATE VECTOR INDEX TechDocEmbeddingIndex
ON Documents2(DocEmbedding)
STORING(NullIfFiltered)
WHERE DocEmbedding IS NOT NULL AND NullIfFiltered IS NOT NULL
OPTIONS (...);
Cuando Spanner ejecuta la siguiente consulta, que tiene filtros que
coinciden con TechDocEmbeddingIndex
, selecciona automáticamente TechDocEmbeddingIndex
y se acelera con él. La consulta solo busca documentos de la categoría "Tecnología". También puedes usar {@FORCE_INDEX=TechDocEmbeddingIndex}
para forzar a Spanner a usar TechDocEmbeddingIndex
explícitamente.
SELECT *
FROM Documents2
WHERE DocEmbedding IS NOT NULL AND NullIfFiltered IS NOT NULL
ORDER BY APPROX_(....)
LIMIT 10;
Siguientes pasos
Consulta más información sobre los vecinos más cercanos aproximados de Spanner.
Consulta más información sobre las funciones GoogleSQL
APPROXIMATE_COSINE_DISTANCE()
,APPROXIMATE_EUCLIDEAN_DISTANCE()
yAPPROXIMATE_DOT_PRODUCT()
.Consulta más información sobre las instrucciones
VECTOR INDEX
de GoogleSQL.Consulta más información sobre las prácticas recomendadas para los índices vectoriales.