En este documento, se muestra cómo ajustar los índices para lograr un rendimiento de consulta más rápido y una mejor recuperación.
Cómo ajustar un índice ScaNN
El índice de ScaNN usa la indexación basada en la cuantificación de árboles. En las técnicas de cuantificación de árboles, los índices aprenden un árbol de búsqueda junto con una función de cuantificación (o hash). Cuando ejecutas una consulta, el árbol de búsqueda se usa para reducir el espacio de búsqueda, mientras que la cuantificación se usa para comprimir el tamaño del índice. Esta poda acelera la puntuación de la similitud (es decir, la distancia) entre el vector de consulta y los vectores de la base de datos.
Para lograr una alta tasa de consultas por segundo (QPS) y una alta recuperación con tus consultas de vecino más cercano, debes particionar el árbol de tu índice ScaNN
de la manera más adecuada para tus datos y tus consultas.
Antes de compilar un índice ScaNN
, completa lo siguiente:
- Asegúrate de que ya se haya creado una tabla con tus datos.
- Asegúrate de que el valor que establezcas para
maintenance_work_mem
y la marcashared_buffers
sea inferior a la memoria total de la máquina para evitar problemas durante la generación del índice.
Parámetros de ajuste
Los siguientes parámetros de índice y marcas de base de datos se usan en conjunto para encontrar el equilibrio correcto entre la recuperación y la QPS. Todos los parámetros se aplican a ambos tipos de índices ScaNN
.
Parámetro de ajuste | Descripción | Tipo de parámetro |
---|---|---|
num_leaves |
Es la cantidad de particiones que se aplicarán a este índice. La cantidad de particiones a las que se aplica un índice cuando se crea afecta su rendimiento. Si aumentas las particiones para una cantidad determinada de vectores, creas un índice más detallado, lo que mejora el rendimiento de la recuperación y las consultas. Sin embargo, esto implica tiempos de creación de índices más largos. Dado que los árboles de tres niveles se compilan más rápido que los de dos niveles, puedes aumentar el num_leaves_value cuando crees un índice de árbol de tres niveles para lograr un mejor rendimiento.
|
Creación de índices |
quantizer |
Es el tipo de cuantificador que deseas usar para el árbol de K-means. El valor predeterminado es SQ8 para mejorar el rendimiento de las consultas.Establece el valor en FLAT para mejorar la recuperación. |
Creación de índices |
enable_pca |
Habilita el análisis de componentes principales (PCA), que es una técnica de reducción de dimensión que se usa para reducir automáticamente el tamaño de la incorporación cuando sea posible. Esta opción está habilitada de forma predeterminada. Establece la opción en false si observas un deterioro en la recuperación. |
Creación de índices |
scann.num_leaves_to_search |
La marca de la base de datos controla la compensación entre la recuperación y la QPS. El valor predeterminado es el 1% del valor establecido en num_leaves . Cuanto mayor sea el valor establecido, mejor será la recuperación, pero se obtendrán QPS más bajas, y viceversa. |
Tiempo de ejecución de la consulta |
scann.max_top_neighbors_buffer_size |
La marca de base de datos especifica el tamaño de la caché que se usa para mejorar el rendimiento de las consultas filtradas a través de la puntuación o clasificación de los vecinos candidatos analizados en la memoria en lugar del disco. El valor predeterminado es 20000 . Cuanto mayor sea el valor establecido, mejor será el QPS en las consultas filtradas, pero se producirá un mayor uso de la memoria y viceversa. |
Tiempo de ejecución de la consulta |
scann.pre_reordering_num_neighbors |
Cuando se establece, la marca de base de datos especifica la cantidad de vecinos candidatos que se deben tener en cuenta durante las etapas de reordenamiento después de que la búsqueda inicial identifica un conjunto de candidatos. Establece este valor en un valor superior a la cantidad de vecinos que deseas que muestre la consulta. Los conjuntos de valores más altos proporcionan una mejor recuperación, pero este enfoque genera una QPS más baja. |
Tiempo de ejecución de la consulta |
max_num_levels |
Es la cantidad máxima de niveles del árbol de agrupación en clústeres con el modelo K-means.
|
Creación de índices |
Cómo ajustar un índice ScaNN
Considera los siguientes ejemplos de índices ScaNN
de dos y tres niveles que muestran cómo se establecen los parámetros de ajuste:
Índice de dos niveles
SET LOCAL scann.num_leaves_to_search = 1;
SET LOCAL scann.pre_reordering_num_neighbors=50;
CREATE INDEX my-scann-index ON my-table
USING scann (vector_column cosine)
WITH (num_leaves = [power(1000000, 1/2)]);
Índice de tres niveles
SET LOCAL scann.num_leaves_to_search = 10;
SET LOCAL scann.pre_reordering_num_neighbors=50;
CREATE INDEX my-scann-index ON my-table
USING scann (vector_column cosine)
WITH (num_leaves = [power(1000000, 2/3)], max_num_levels = 2);
Cualquier operación de inserción o actualización en una tabla en la que ya se generó un índice ScaNN
afecta la forma en que el árbol aprendido optimiza el índice. Si tu tabla es propensa a actualizaciones o inserciones frecuentes, te recomendamos que vuelvas a indexar periódicamente el índice ScaNN
existente para mejorar la precisión de la recuperación.
Puedes supervisar las métricas de índice para determinar la cantidad de mutaciones creadas desde que se creó el índice y, luego, volver a indexar según corresponda. Para obtener más información sobre las métricas, consulta Métricas del índice vectorial.
Prácticas recomendadas para el ajuste
Según el tipo de índice ScaNN
que planeas usar, las recomendaciones para ajustarlo varían. En esta sección, se proporcionan recomendaciones para ajustar los parámetros de índice para lograr un equilibrio óptimo entre la recuperación y la QPS.
Índice de árbol de dos niveles
Para aplicar recomendaciones que te ayuden a encontrar los valores óptimos de num_leaves
y num_leaves_to_search
para tu conjunto de datos, sigue estos pasos:
- Crea el índice
ScaNN
connum_leaves
establecido en la raíz cuadrada del recuento de filas de la tabla indexada. - Ejecuta tus consultas de prueba y aumenta el valor de
scann.num_of_leaves_to_search
hasta que alcances el rango de recuperación objetivo, por ejemplo, el 95%. Para obtener más información sobre el análisis de tus consultas, consulta Cómo analizar tus consultas. - Toma nota de la proporción entre
scann.num_leaves_to_search
ynum_leaves
que se usará en los pasos posteriores. Esta proporción proporciona una aproximación alrededor del conjunto de datos que te ayudará a lograr la recuperación objetivo.
Si trabajas con vectores de alta dimensión (500 dimensiones o más) y deseas mejorar la recuperación, intenta ajustar el valor descann.pre_reordering_num_neighbors
. Como punto de partida, establece el valor en100 * sqrt(K)
, dondeK
es el límite que estableciste en tu consulta. - Si tu QPS es demasiado baja después de que tus consultas alcancen una recuperación objetivo, sigue estos pasos:
- Vuelve a crear el índice y aumenta el valor de
num_leaves
yscann.num_leaves_to_search
según las siguientes instrucciones:- Establece
num_leaves
en un factor mayor de la raíz cuadrada de tu recuento de filas. Por ejemplo, si el índice tienenum_leaves
establecido en la raíz cuadrada de tu recuento de filas, intenta configurarlo para que duplique la raíz cuadrada. Si el valor ya es el doble, intenta configurarlo para que triplique la raíz cuadrada. - Aumenta
scann.num_leaves_to_search
según sea necesario para mantener su proporción connum_leaves
, que anotaste en el paso 3. - Establece
num_leaves
en un valor menor o igual que el recuento de filas dividido por 100.
- Establece
- Vuelve a ejecutar las consultas de prueba.
Mientras ejecutas las consultas de prueba, experimenta con la reducción de
scann.num_leaves_to_search
y busca un valor que aumente las QPS y mantenga alta la recuperación. Prueba diferentes valores descann.num_leaves_to_search
sin volver a compilar el índice.
- Vuelve a crear el índice y aumenta el valor de
- Repite el paso 4 hasta que el QPS y el rango de recuperación alcancen valores aceptables.
Índice de árbol de tres niveles
Además de las recomendaciones para el índice ScaNN
de árbol de dos niveles, usa la siguiente guía y los pasos para ajustar el índice:
- Aumentar
max_num_levels
de1
para un árbol de dos niveles a2
para un árbol de tres niveles reduce significativamente el tiempo de creación de un índice, pero a costa de la precisión de la recuperación. Establecemax_num_levels
con la siguiente recomendación:- Establece el valor en
2
si la cantidad de filas de vectores supera los 100 millones de filas. - Establece el valor en
1
si la cantidad de filas vectoriales es inferior a 10 millones de filas. - Establece el valor en
1
o2
si la cantidad de filas de vectores está entre 10 millones y 100 millones de filas, según el equilibrio entre el tiempo de creación del índice y la precisión de recuperación que necesitas.
- Establece el valor en
Para aplicar recomendaciones y encontrar el valor óptimo de los parámetros de índice num_leaves
y max_num_levels
, sigue estos pasos:
Crea el índice
ScaNN
con las siguientes combinaciones denum_leaves
ymax_num_levels
según tu conjunto de datos:- Filas de vectores superiores a 100 millones de filas: Establece
max_num_levels
como2
ynum_leaves
comopower(rows, ⅔)
. - Filas vectoriales de menos de 100 millones de filas: Establece
max_num_levels
como1
ynum_leaves
comosqrt(rows)
. - Filas vectoriales entre 10 y 100 millones de filas: Primero, establece
max_num_levels
como1
ynum_leaves
comosqrt(rows)
.
- Filas de vectores superiores a 100 millones de filas: Establece
Ejecuta tus consultas de prueba. Para obtener más información sobre el análisis de consultas, consulta Cómo analizar tus consultas.
Si el tiempo de creación del índice es satisfactorio, conserva el valor de
max_num_levels
y experimenta con el valor denum_leaves
para obtener una precisión de recuperación óptima.Si no estás conforme con el tiempo de creación del índice, haz lo siguiente:
Si el valor de
max_num_levels
es1
, descarta el índice. Vuelve a compilar el índice con el valor demax_num_levels
establecido en2
.Ejecuta las consultas y ajusta el valor de
num_leaves
para obtener una precisión de recuperación óptima.Si el valor de
max_num_levels
es2
, descarta el índice. Vuelve a compilar el índice con el mismo valor demax_num_levels
y ajusta el valor denum_leaves
para obtener una precisión de recuperación óptima.
Cómo ajustar un índice IVF
Ajustar los valores que estableces para los parámetros lists
, ivf.probes
y quantizer
podría ayudar a optimizar el rendimiento de tu aplicación:
Parámetro de ajuste | Descripción | Tipo de parámetro |
---|---|---|
lists |
Es la cantidad de listas creadas durante la compilación del índice. El punto de partida para establecer este valor es (rows)/1000 para hasta un millón de filas y sqrt(rows) para más de un millón de filas. |
Creación de índices |
quantizer |
Es el tipo de cuantificador que deseas usar para el árbol de K-means. El valor predeterminado es SQ8 para mejorar el rendimiento de las consultas. Establece el valor en FLAT para mejorar la recuperación. |
Creación de índices |
ivf.probes |
la cantidad de listas más cercanas que se explorarán durante la búsqueda. El punto de partida de este valor es sqrt(lists) . |
Tiempo de ejecución de la consulta |
Considera el siguiente ejemplo que muestra un índice IVF
con los parámetros de ajuste establecidos:
SET LOCAL ivf.probes = 10;
CREATE INDEX my-ivf-index ON my-table
USING ivf (vector_column cosine)
WITH (lists = 100, quantizer = 'SQ8');
Cómo ajustar un índice IVFFlat
Ajustar los valores que estableces para los parámetros lists
y ivfflat.probes
puede ayudar a optimizar el rendimiento de la aplicación:
Parámetro de ajuste | Descripción | Tipo de parámetro |
---|---|---|
lists |
Es la cantidad de listas creadas durante la compilación del índice. El punto de partida para establecer este valor es (rows)/1000 para hasta un millón de filas y sqrt(rows) para más de un millón de filas. |
Creación de índices |
ivfflat.probes |
Es la cantidad de listas más cercanas que se explorarán durante la búsqueda. El punto de partida de este valor es sqrt(lists) . |
Tiempo de ejecución de la consulta |
Antes de compilar un índice IVFFlat
, asegúrate de que la marca max_parallel_maintenance_workers
de tu base de datos esté configurada en un valor suficiente para acelerar la creación del índice en tablas grandes.
Considera el siguiente ejemplo que muestra un índice IVFFlat
con los parámetros de ajuste establecidos:
SET LOCAL ivfflat.probes = 10;
CREATE INDEX my-ivfflat-index ON my-table
USING ivfflat (vector_column cosine)
WITH (lists = 100);
Cómo ajustar un índice HNSW
Ajustar los valores que estableces para los parámetros m
, ef_construction
y hnsw.ef_search
puede ayudar a optimizar el rendimiento de la aplicación.
Parámetro de ajuste | Descripción | Tipo de parámetro |
---|---|---|
m |
Es la cantidad máxima de conexiones por nodo en el gráfico. Puedes comenzar con el valor predeterminado como 16 (predeterminado) y experimentar con valores más altos según el tamaño de tu conjunto de datos. |
Creación de índices |
ef_construction |
Es el tamaño de la lista de candidatos dinámicos que se mantiene durante la construcción del gráfico, que actualiza constantemente los mejores candidatos actuales para los vecinos más cercanos de un nodo. Establece este valor en cualquier valor superior al doble del valor de m , por ejemplo, 64 (predeterminado). |
Creación de índices |
ef_search |
Es el tamaño de la lista de candidatos dinámicos que se usa durante la búsqueda. Puedes comenzar a establecer este valor en m o ef_construction y, luego, cambiarlo mientras observas la recuperación. El valor predeterminado es 40 . |
Tiempo de ejecución de la consulta |
Considera el siguiente ejemplo que muestra un índice hnsw
con los parámetros de ajuste establecidos:
SET LOCAL hnsw.ef_search = 40;
CREATE INDEX my-hnsw-index ON my-table
USING hnsw (vector_column cosine)
WITH (m = 16, ef_construction = 200);
Analiza tus consultas
Usa el comando EXPLAIN ANALYZE
para analizar las estadísticas de tus consultas, como se muestra en la siguiente consulta en SQL de ejemplo.
EXPLAIN ANALYZE SELECT result-column FROM my-table
ORDER BY EMBEDDING_COLUMN ::vector
USING INDEX my-scann-index
<-> embedding('textembedding-gecko@003', 'What is a database?')
LIMIT 1;
La respuesta de ejemplo QUERY PLAN
incluye información como el tiempo transcurrido, la cantidad de filas analizadas o devueltas y los recursos utilizados.
Limit (cost=0.42..15.27 rows=1 width=32) (actual time=0.106..0.132 rows=1 loops=1)
-> Index Scan using my-scann-index on my-table (cost=0.42..858027.93 rows=100000 width=32) (actual time=0.105..0.129 rows=1 loops=1)
Order By: (embedding_column <-> embedding('textgecko@003', 'What is a database?')::vector(768))
Limit value: 1
Planning Time: 0.354 ms
Execution Time: 0.141 ms
Consulta las métricas del índice vectorial
Puedes usar las métricas del índice vectorial para revisar el rendimiento de tu índice vectorial, identificar áreas de mejora y ajustar el índice según las métricas, si es necesario.
Para ver todas las métricas del índice vectorial, ejecuta la siguiente consulta en SQL, que usa la vista pg_stat_ann_indexes
:
SELECT * FROM pg_stat_ann_indexes;
Para obtener más información sobre la lista completa de métricas, consulta Métricas del índice vectorial.