El índice ScaNN es un índice de cuantización basado en árboles creado por Google para la búsqueda aproximada de vecinos más cercanos. Proporciona un tiempo de compilación de índices más bajo y un espacio en memoria más pequeño en comparación con HNSW. Además, proporciona QPS más rápidas en comparación con HNSW según la carga de trabajo.
Antes de comenzar
Antes de comenzar a crear índices, debes completar los siguientes requisitos previos.
Los vectores de embedding se agregan a una tabla en tu base de datos de AlloyDB Omni.
Si intentas generar un índice de ScaNN en una tabla vacía o particionada, es posible que encuentres algunos problemas. Para obtener más información sobre los errores generados, consulta Soluciona problemas de errores del índice de ScaNN. Para crear un índice en una tabla vacía o pequeña, consulta Creación de índices diferida para tablas vacías o casi vacías.
Se instalaron las extensiones
vectoryalloydb_scann:CREATE EXTENSION IF NOT EXISTS alloydb_scann CASCADE;Cuando instalas la extensión
alloydb_scann, se comprueba automáticamente si la extensiónvectorestá instalada y, si no es así, se instala. No es necesario que instalesvectorpor separado de forma manual.Si deseas crear un índice de ScaNN de cuatro niveles, primero debes habilitar la función de versión preliminar para tu instancia de AlloyDB Omni. Para habilitar la función de versión preliminar, elige uno de los siguientes dos métodos:
Habilita la marca de base de datos
scann.enable_preview_features.Para obtener más información sobre cómo configurar marcas de base de datos, consulta Configura marcas de base de datos.
Establece la marca de base de datos
scann.max_allowed_num_levelsen3a nivel de sesión o de instancia. Para establecer la marca a nivel de la sesión, ejecuta el siguiente comando:SET scann.max_allowed_num_levels = 3;Para establecer la marca a nivel de la instancia, ejecuta
gcloud alloydb alloydb instances updatecon el campo--database-flags.
Crea un índice ajustado automáticamente
Los índices ScaNN ajustados automáticamente simplifican la creación de índices, ya que permiten que AlloyDB Omni administre y ajuste la estructura del índice. Si necesitas un control detallado sobre el ajuste del índice, crea un índice de ScaNN ajustado de forma manual.
Los índices ajustados automáticamente se pueden optimizar de dos maneras:
- (Predeterminado) Vector Search recall y latencia a costa del tiempo de compilación del índice
- Equilibra el tiempo de compilación del índice y el rendimiento de la búsqueda
Para crear un índice de ScaNN ajustado automáticamente, ejecuta el siguiente comando.
CREATE INDEX INDEX_NAME ON TABLE
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
Reemplaza lo siguiente:
INDEX_NAME: Es el nombre del índice que deseas crear. Por ejemplo,my_scann_indexLos nombres de los índices se comparten en toda la base de datos. Verifica que cada nombre de índice sea único para cada tabla de tu base de datos.TABLE: Es la tabla a la que se agregará el índice.EMBEDDING_COLUMN: Columna que almacena datosvector.DISTANCE_FUNCTION: Función de distancia que se usará con este índice. Elige una de estas opciones:Distancia de L2:
l2Producto escalar:
dot_productDistancia de coseno:
cosine
Este comando crea un índice de ScaNN optimizado para el rendimiento de la búsqueda. Si deseas cambiar este parámetro de configuración, ejecuta el siguiente comando:
CREATE INDEX INDEX_NAME ON TABLE
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
WITH (MODE='AUTO',
OPTIMIZATION='OPTIMIZATION')
Reemplaza lo siguiente:
INDEX_NAME: Es el nombre del índice que deseas crear. Por ejemplo,my_scann_indexLos nombres de los índices se comparten en toda la base de datos. Verifica que cada nombre de índice sea único para cada tabla de tu base de datos.TABLE: Es la tabla a la que se agregará el índice.EMBEDDING_COLUMN: Columna que almacena datosvector.DISTANCE_FUNCTION: Función de distancia que se usará con este índice. Elige una de estas opciones:Distancia de L2:
l2Producto escalar:
dot_productDistancia de coseno:
cosine
(Opcional)
OPTIMIZATION: Configúralo con uno de los siguientes valores:(Predeterminado)
SEARCH_OPTIMIZED: Optimiza la recuperación y la latencia de la búsqueda de vectores a costa de tiempos de compilación de índices más largos.BALANCED: Equilibrar el tiempo de compilación del índice y el rendimiento de la búsqueda.
Si se establece
OPTIMIZATION, también se debe incluirMODE='AUTO'.
Crea un índice ajustado manualmente
Si tu aplicación tiene requisitos específicos para los tiempos de recuperación y compilación de índices, puedes crear y ajustar el índice de ScaNN de forma manual.
Para crear de forma manual un índice de ScaNN para una columna que contenga embeddings de vectores almacenados, consulta los siguientes comandos.
Índice de árbol de dos niveles
CREATE INDEX INDEX_NAME ON TABLE USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) WITH (mode='MANUAL', num_leaves=NUM_LEAVES_VALUE, quantizer=QUANTIZER);
-
INDEX_NAME: Es el nombre del índice que deseas crear. Por ejemplo:my_scann_index. Los nombres de los índices se comparten en tu base de datos. Asegúrate de que cada nombre de índice sea único para cada tabla de tu base de datos. -
TABLE: Es la tabla a la que se agregará el índice. -
EMBEDDING_COLUMN: columna que almacena datos de tipo "vector". -
DISTANCE_FUNCTION: es la función de distancia que se usará con este índice. Elige una de las siguientes opciones:- Distancia de L2:
l2 - Producto escalar:
dot_product - Distancia de coseno:
cosine
- Distancia de L2:
-
NUM_LEAVES_VALUE: Es la cantidad de particiones que se aplicarán a este índice. Se establece en cualquier valor entre 1 y 30 millones. Para obtener más información sobre cómo elegir este valor, consulta Ajusta un índice deScaNN. -
QUANTIZER: Tipo de cuantificador que se usará. Ten en cuenta que el índice de ScaNN se puede cargar en el motor de columnas para acelerar aún más la búsqueda de vectores. Elige una de las siguientes opciones:-
(Predeterminado)
SQ8: Proporciona un equilibrio entre el rendimiento de las consultas y una pérdida mínima de recuperación. Por lo general, es menos del 1 o 2%. -
(Versión preliminar)
AH: La compresión del hash asimétrico (AH) es hasta 4 veces mayor en comparación conSQ8. Para mejorar el rendimiento de las consultas cuando el motor de columnas está habilitado y los datos del índice y de la tabla se propagan en el motor de columnas, considera esto para mejorar el rendimiento de las consultas. Para obtener más información, consulta las prácticas recomendadas para ajustar ScaNN. -
FLAT: proporciona la recuperación más alta, del 99% o más, a costa del rendimiento de la búsqueda.
-
(Predeterminado)
Índice de árbol de tres niveles
CREATE INDEX INDEX_NAME ON TABLE USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) WITH (mode='MANUAL', num_leaves=NUM_LEAVES_VALUE, quantizer=QUANTIZER, auto_maintenance=AUTO_MAINTENANCE, max_num_levels = 2);
-
INDEX_NAME: Es el nombre del índice que deseas crear. Por ejemplo:my_scann_index. Los nombres de los índices se comparten en tu base de datos. Asegúrate de que cada nombre de índice sea único para cada tabla de tu base de datos. -
TABLE: Es la tabla a la que se agregará el índice. -
EMBEDDING_COLUMN: columna que almacena datos de tipo "vector". -
DISTANCE_FUNCTION: es la función de distancia que se usará con este índice. Elige una de las siguientes opciones:- Distancia de L2:
l2 - Producto escalar:
dot_product - Distancia de coseno:
cosine
- Distancia de L2:
-
NUM_LEAVES_VALUE: Es la cantidad de particiones que se aplicarán a este índice. Se establece en cualquier valor entre 1 y 30 millones. Para obtener más información sobre cómo elegir este valor, consulta Cómo ajustar un índice deScaNN. -
QUANTIZER: Tipo de cuantificador que se usará. Ten en cuenta que el índice de ScaNN se puede cargar en el motor de columnas para acelerar aún más la búsqueda de vectores. Elige una de las siguientes opciones:-
(Predeterminado)
SQ8: Proporciona un equilibrio entre el rendimiento de las consultas y una pérdida mínima de recuperación. Por lo general, es menos del 1 o 2%. -
(Versión preliminar)
AH: La compresión del hash asimétrico (AH) es hasta 4 veces mayor en comparación conSQ8. Para obtener un mejor rendimiento de las consultas cuando el motor de columnas está habilitado y los datos de índice y tabla se propagan en el motor de columnas, considera esta opción para obtener un mejor rendimiento de las consultas. Para obtener más información, consulta las prácticas recomendadas para ajustar ScaNN. -
FLAT: Proporciona la recuperación más alta, un 99% o más, a costa del rendimiento de la búsqueda.
-
(Predeterminado)
-
(Opcional)
AUTO_MAINTENANCE: Controla si el mantenimiento automático del índice está habilitado o inhabilitado. Para obtener más información sobre el mantenimiento automático, consulta Mantén índices vectoriales.-
(Predeterminado)
ON: AlloyDB Omni realiza un mantenimiento automático en el índice. -
OFF: AlloyDB Omni no realiza mantenimiento automático en el índice.
-
(Predeterminado)
-
max_num_levels = 2: Es la cantidad máxima de niveles de centroides del árbol de agrupamiento de K-means. Establece este parámetro en2para crear un índice de tres niveles.
Índice de árbol de cuatro niveles
CREATE INDEX INDEX_NAME ON TABLE USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) WITH (mode='MANUAL', num_leaves=NUM_LEAVES_VALUE, quantizer=QUANTIZER, auto_maintenance=AUTO_MAINTENANCE, max_num_levels = 3);
-
INDEX_NAME: Es el nombre del índice que deseas crear. Por ejemplo:my_scann_index. Los nombres de los índices se comparten en tu base de datos. Asegúrate de que cada nombre de índice sea único para cada tabla de tu base de datos. -
TABLE: Es la tabla a la que se agregará el índice. -
EMBEDDING_COLUMN: columna que almacena datos de tipo "vector". -
DISTANCE_FUNCTION: es la función de distancia que se usará con este índice. Elige una de las siguientes opciones:- Distancia de L2:
l2 - Producto escalar:
dot_product - Distancia de coseno:
cosine
- Distancia de L2:
-
NUM_LEAVES_VALUE: Cantidad de particiones que se aplicarán a este índice. Se puede establecer en cualquier valor entre 1 y 30 millones. Para obtener más información sobre cómo elegir este valor, consulta Ajusta un índice deScaNN. -
QUANTIZER: Es el tipo de cuantificador que se usará. Ten en cuenta que el índice de ScaNN se puede cargar en el motor de columnas para acelerar aún más la búsqueda de vectores. Elige una de las siguientes opciones:-
(Predeterminado)
SQ8: Proporciona un equilibrio entre el rendimiento de las consultas y una pérdida mínima de recuperación. Por lo general, es menos del 1 o 2%. -
Vista previa
AH: El hashing asimétrico (AH) se comprime hasta 4 veces en comparación conSQ8. Para mejorar el rendimiento de las consultas cuando el motor de columnas está habilitado y los datos del índice y de la tabla se propagan en el motor de columnas, considera esto para mejorar el rendimiento de las consultas. Para obtener más información, consulta Prácticas recomendadas para ajustar ScaNN. -
FLAT: Proporciona la recuperación más alta, un 99% o más, a costa del rendimiento de la búsqueda.
-
(Predeterminado)
-
AUTO_MAINTENANCE(opcional): Controla si el mantenimiento automático en el índice está habilitado o inhabilitado. Para obtener más información sobre el mantenimiento automático, consulta Cómo mantener índices vectoriales.-
(Predeterminado)
ON: AlloyDB Omni habilita el mantenimiento automático en el índice. -
OFF: AlloyDB Omni inhabilita el mantenimiento automático en el índice.
-
(Predeterminado)
-
max_num_levels = 3: Es la cantidad máxima de niveles de centroides del árbol de agrupamiento en clústeres de k-means. Establece este parámetro en3para crear un índice de cuatro niveles.
Cómo convertir un índice ajustado manualmente en un índice ajustado automáticamente
Para convertir un índice ajustado manualmente en un índice ajustado automáticamente, completa los siguientes pasos:
Restablece todos los parámetros de consulta definidos para tu índice ajustado manualmente.
ALTER INDEX INDEX_NAME RESET (PARAMETER_NAME);Reemplaza las siguientes variables:
INDEX_NAME: Es el nombre del índice que deseas convertir. Por ejemplo,my_scann_indexLos nombres de los índices se comparten en toda la base de datos. Verifica que cada nombre de índice sea único para cada tabla de tu base de datos.PARAMETER_NAME: Es una lista separada por comas que contiene los nombres de los parámetros de consulta que deseas restablecer. Por ejemplo,num_leaves, quantizationTen en cuenta que debes restablecer todos los demás parámetros de consulta antes de restablecer
num_leaves.
Vuelve a indexar tu índice ajustado manualmente para convertirlo en un índice ajustado automáticamente.
REINDEX INDEX CONCURRENTLY INDEX_NAME;
Crea un índice de ScaNN para los tipos de datos de real[]
Para crear un índice para una columna de embedding que use el tipo de datos real[]
en lugar de vector, convierte la columna en el tipo de datos vector:
CREATE INDEX INDEX_NAME ON TABLE
USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)
Reemplaza lo siguiente:
INDEX_NAME: Es el nombre del índice que deseas crear. Por ejemplo,my_scann_indexLos nombres de los índices se comparten en toda la base de datos. Verifica que cada nombre de índice sea único para cada tabla de tu base de datos.TABLE: Es la tabla a la que se agregará el índice.DIMENSIONS: Es la cantidad de dimensiones que admite el modelo.EMBEDDING_COLUMN: es una columna que almacena datosvector.DISTANCE_FUNCTION: Función de distancia que se usará con este índice. Elige una de estas opciones:Distancia de L2:
l2Producto escalar:
dot_productDistancia de coseno:
cosine
Cómo ver el progreso de la indexación
Para ver el progreso de la indexación, usa la vista pg_stat_progress_create_index:
SELECT * FROM pg_stat_progress_create_index;
La columna phase muestra el estado actual de la creación del índice. Una vez que
se completa la fase de compilación del índice, la fila del índice no es visible.
Crea un índice diferido para tablas vacías o con una cantidad insuficiente de filas
De forma predeterminada, no puedes crear un índice de ScaNN en una tabla que esté vacía o que tenga menos
filas que el valor de la opción de índice num_leaves.
Para evitar esta limitación, habilita la creación de índices diferida para permitir que
AlloyDB Omni aplace la creación de índices hasta que la cantidad de filas de la
tabla alcance el umbral que define num_leaves. Una vez que se alcanza el umbral, AlloyDB Omni inicia la compilación del índice en segundo plano.
Esta operación diferida es un proceso que no bloquea, lo que permite que otras operaciones de la base de datos, como las lecturas y escrituras, continúen sin interrupciones. Dado que la recompilación del índice se realiza en segundo plano, la creación diferida del índice es adecuada cuando las tablas incorporan filas de datos en lotes pequeños. La recompilación del índice se activa automáticamente después de que la cantidad de filas alcanza el umbral.
Sin embargo, si planeas insertar una gran cantidad de filas en la tabla en una sola transacción, te recomendamos que dividas la transacción en varias o que generes un índice de ScaNN sin habilitar la creación diferida del índice.
Habilita la creación de índices diferida
Para habilitar la creación de índices diferida, sigue estos pasos:
Asegúrate de que la marca
scann.enable_index_maintenancey una de las siguientes marcas estén habilitadas:scann.enable_preview_features: Esta marca también habilita otras funciones de vista previa.scann.enable_index_with_insufficient_data: Esta marca habilita de forma explícita solo la función de creación de índices diferida.
Para configurar su uso, utiliza la CLI de
gcloud:Para habilitar la creación de índices diferida junto con otras funciones de vista previa, haz lo siguiente:
gcloud alloydb instances update INSTANCE_ID \ --database-flags scann.enable_index_maintenance=on \ --database-flags scann.enable_preview_features=on \ --region=REGION_ID \ --cluster=CLUSTER_ID \ --project=PROJECT_IDPara habilitar la creación de índices diferida de forma explícita sin habilitar otras funciones en versión preliminar, haz lo siguiente:
gcloud alloydb instances update INSTANCE_ID \ --database-flags scann.enable_index_maintenance=on \ --database-flags scann.enable_index_with_insufficient_data=on \ --region=REGION_ID \ --cluster=CLUSTER_ID \ --project=PROJECT_ID
Reemplaza lo siguiente:
INSTANCE_ID: El ID de la instancia.REGION_ID: Es la región en la que se coloca la instancia, por ejemplo,us-central1.CLUSTER_ID: Es el ID del clúster en el que se coloca la instancia.PROJECT_ID: Es el ID del proyecto en el que se coloca el clúster.
Crea un índice de ScaNN. Si creas un índice en modo manual, asegúrate de que el parámetro
auto_maintenanceesté configurado comoon. Para obtener más información, consulta Crea un índice ajustado de forma manual.
Limitaciones
- El proceso en segundo plano de creación automática de índices usa valores de marcas a nivel de la base de datos. Incluso si configuras marcas a nivel de la sesión con el comando
SET LOCAL, el proceso considera el valor de la marca establecido a nivel de la base de datos. - Si planeas insertar de forma masiva una gran cantidad de datos en una tabla vacía en una sola transacción, te recomendamos que ejecutes la transacción de inserción única y, luego, crees un índice de ScaNN.
Forzar la creación de índices en tablas vacías o pequeñas
AlloyDB Omni usa validaciones para evitar la creación de un índice de ScaNN en una tabla vacía o con muy pocas filas por los siguientes motivos:
El índice de ScaNN se entrena con datos insuficientes. Esto puede generar una recuperación deficiente para las búsquedas de similitud de vectores.
El rendimiento de escritura en la base de datos podría disminuir.
Te recomendamos que difieras la creación de índices para evitar un rendimiento deficiente.
Sin embargo, en algunas situaciones de desarrollo o prueba, es posible que debas crear un
índice en una tabla vacía o pequeña. En estos casos, puedes forzar la creación de índices. Ten en cuenta que forzar la creación de índices requiere privilegios de SUPERUSER.
Para forzar la creación de índices, completa los siguientes pasos:
Establece el parámetro
scann.allow_blocked_operationsa nivel de la sesión entrueen la base de datos:SET scann.allow_blocked_operations = true;Si el usuario que usas para ejecutar estas consultas no tiene privilegios de
SUPERUSER, asígnalos:CREATE USER USERNAME WITH SUPERUSER PASSWORD PASSWORD;Reemplaza las siguientes variables:
USERNAME: Es el nombre del usuario al que deseas otorgar privilegios deSUPERUSER.PASSWORD: Es la contraseña del usuario.
Compila índices en paralelo
Para compilar tu índice con mayor rapidez, AlloyDB Omni puede generar de forma automática varios trabajadores paralelos según tu conjunto de datos y el tipo de índice que elijas. Esto suele activarse cuando se crea un índice de ScaNN de tres o cuatro niveles, o si tu conjunto de datos supera los 100 millones de filas.
Aunque AlloyDB Omni optimiza automáticamente la cantidad de trabajadores paralelos, puedes ajustarlos con los siguientes parámetros de planificación de consultas de PostgreSQL:
Para evitar problemas de falta de memoria cuando crees el índice de ScaNN, asegúrate de que las marcas de base de datos
maintenance_work_mem
y
shared_buffers
estén configuradas con un valor inferior a la memoria total de la máquina.
Ejecuta una consulta
Después de almacenar e indexar las incorporaciones en tu base de datos, puedes comenzar
a consultar tus datos. No puedes ejecutar búsquedas masivas con la extensión alloydb_scann.
Para encontrar los vecinos semánticos más cercanos a una cadena de texto, puedes usar la función google_ml.embedding() para traducir el texto a un vector.
Debido a que google_ml.embedding() devuelve un array real, debes convertir de forma explícita
la llamada a función en vector antes de aplicarla a uno de los operadores de vecino más cercano, por ejemplo, <-> para la distancia L2. Luego, estos operadores pueden usar el índice de ScaNN para encontrar las filas de la base de datos con las incorporaciones más similares desde el punto de vista semántico.
SELECT * FROM TABLE
ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY
google_ml.embedding(
model_id => 'MODEL_ID',
content => 'CONTENT')::vector
LIMIT ROW_COUNT
Reemplaza las siguientes variables:
TABLE: Es la tabla que contiene la incorporación con la que se comparará el texto.EMBEDDING_COLUMN: es la columna que contiene las incorporaciones almacenadas.DISTANCE_FUNCTION_QUERY: Es la función de distancia que se usará con esta consulta. Elige el equivalente de consulta para la función de distancia cuando creaste el índice:Distancia L2:
<->Producto interno:
<#>Distancia de coseno:
<=>
MODEL_ID: Es el ID del modelo de incorporación registrado que deseas usar.CONTENT: Es la cadena de texto que deseas traducir en una incorporación y buscar.ROW_COUNT: Es la cantidad de filas que se mostrarán. Por ejemplo, especifica1si deseas la mejor coincidencia única.
¿Qué sigue?
- Ejecutar búsquedas de similitud de vectores
- Ajusta el rendimiento de las consultas vectoriales
- Métricas de índices vectoriales
- Obtén información para crear un asistente de compras inteligente con AlloyDB, pgvector y la administración de extremos de modelos.