Buscar y filtrar con incrustaciones de vectores

En esta página se describen las diferentes formas de consultar las inserciones de vectores. Para obtener una descripción general de las búsquedas de similitud ANN y KNN, consulta Búsquedas vectoriales.

Buscar vecinos más cercanos aproximados (ANN)

Para realizar una búsqueda de vecinos más cercanos aproximada, usa la función approx_distance en una cláusula SELECT y ORDER BY. Debes usar una cláusula LIMIT en una búsqueda de ANN. También puedes obtener el valor de la distancia poniendo approx_distance en una lista SELECT.

Usa la siguiente sintaxis para las consultas de ANN:

# Ordering by distance
SELECT title
FROM books
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
LIMIT 4;

# Selecting the distance value
SELECT
  approx_distance(
    embedding_name,
    string_to_vector('[1,2,3]'),
    'distance_measure=cosine,num_leaves_to_search=3')
    dist
FROM table
ORDER BY dist
LIMIT limit_value;

La función approx_distance usa las siguientes opciones:

  • embedding: usa el nombre de la columna de embedding de vectores de la tabla base.
  • string_to_vector o vector_to_string: convierte un vector en una cadena y una cadena en un vector para que el vector sea legible.
  • distance_measure: especifica la medida de distancia que se va a usar en una búsqueda de similitud de vectores. Este valor debe coincidir con el que haya definido en el parámetro distance_measure al crear el índice. Este parámetro es obligatorio. Los valores posibles de este parámetro son:
    • COSINE
    • L2_SQUARED
    • DOT_PRODUCT
  • num_leaves_to_search: opcional. Especifica el número de hojas que se van a sondear en una búsqueda de similitudes de vectores ANN. Si no especifica el número de hojas, Cloud SQL usará un valor generado en función del tamaño de la tabla, el número de hojas del índice vectorial y otros factores. Puedes ver este valor en information_schema.innodb_vector_indexes. Te recomendamos que ajustes num_leaves_to_search para conseguir el mejor equilibrio entre la calidad de la búsqueda y el rendimiento de tu carga de trabajo específica. Si se aumenta, afecta al rendimiento, pero mejora el recuerdo.

En el siguiente ejemplo se muestra cómo usar approx_distance para encontrar las K filas más cercanas mediante la medida de distancia l2_squared y ordenar los resultados por distancia.

# Ordering by distance
SELECT title
FROM books
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'),
                         'distance_measure=l2_squared')
LIMIT 4;

# Selecting the distance value
SELECT
    approx_distance
        (embedding, string_to_vector('[1,2,3]'),
         'distance_measure=l2_squared') dist
FROM table
ORDER BY dist
LIMIT 4;

Filtrar resultados de consultas de approx_distance

Puedes usar la función approx_distance con condiciones WHERE que filtren los resultados de la consulta con un predicado no vectorial para realizar un post-filtrado. La función approx_distance se evalúa antes de aplicar el filtro, lo que significa que el número de resultados devueltos no es determinista.

Por ejemplo, en la siguiente consulta:

SELECT id FROM products WHERE price < 100
ORDER BY approx_distance(embedding, @query_vector,'distance_measure=cosine')
LIMIT 11;

La función approx_distance devuelve los 11 vecinos más cercanos a la consulta vector independientemente del precio. En el filtrado posterior, se seleccionan los productos con un precio inferior a 100. Es posible que todos los vecinos más cercanos tengan un precio inferior a 100, por lo que la consulta devuelve 11 resultados. Por otro lado, si ninguno de los vecinos más cercanos tiene un precio inferior a 100, se devuelven 0 filas.

Si prevés que el filtro de la condición WHERE es muy selectivo, la búsqueda exacta (KNN) es una opción que te ayudará a asegurarte de que se devuelva un número suficiente de filas.

Otra opción es usar el filtrado iterativo para analizar una mayor parte del índice de búsqueda de ANN.

Usar el filtrado iterativo para aumentar los resultados de búsqueda de ANN

Puedes usar el filtrado iterativo cuando los filtros selectivos de la cláusula WHERE de tu consulta de búsqueda de ANN estén produciendo menos resultados que el número de resultados especificado en la cláusula LIMIT.

Por ejemplo, en la siguiente consulta, si habilitas el filtrado iterativo, la consulta analiza una mayor parte del índice de vectores, menos el primer conjunto de resultados filtrados.

EXPLAIN FORMAT=TREE
SELECT * FROM t1 WHERE next_id BETWEEN 15 AND 100
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
LIMIT 10;

EXPLAIN
-> Limit: 10 row(s)  (rows=10)
   -> Vector index loop with iterative filtering
      -> Vector index scan on t1
      -> Filter: (t1.next_id between 15 and 100)
         -> Single-row index lookup on t1 using PRIMARY (id=t1.id)

Obtienes más vecinos del índice de vectores de búsqueda de forma iterativa hasta alcanzar el máximo configurado (cloudsql_vector_iterative_filtering_max_neighbors). Las coincidencias de los filtros se tienen en cuenta en LIMIT y se eliminan de las búsquedas adicionales en el índice vectorial.

Habilitar el filtrado iterativo

De forma predeterminada, el filtrado iterativo está desactivado en todas las sesiones y las instancias de Cloud SQL.

Para habilitar el filtrado iterativo en una sesión, usa la siguiente instrucción SQL.

SET SESSION cloudsql_vector_iterative_filtering=on;

También puede habilitar el filtrado iterativo de forma global para todas las sesiones de cliente que se conecten a la instancia. Para ello, defina la marca en la instancia. Para definir una marca en una instancia, consulta Definir una marca de base de datos.

Para obtener más información sobre cómo definir variables de sistema a nivel de sesión o global, consulta el artículo Using System Variables (Usar variables de sistema) de la documentación de MySQL.

Ajustar el filtrado iterativo

Para controlar cuántos vecinos más cercanos se devuelven en una consulta de búsqueda de ANN con el filtrado iterativo habilitado, puedes usar la variable de sistema global o de sesión cloudsql_vector_iterative_filtering_max_neighbors. Puedes usar esta configuración para aumentar el número de vecinos más cercanos que se solicitan. Sin embargo, para evitar almacenar demasiados resultados en la memoria, el máximo de esta variable es 1000.

Para definir esta variable en una sesión, usa la siguiente instrucción SQL:

SET cloudsql_vector_iterative_filtering_max_neighbors=600;

El valor predeterminado es 500 y el número mínimo es 10.

Limitaciones

Estas son algunas de las limitaciones que se aplican al usar el filtrado iterativo:

  • No es una garantía: cuando usas el filtrado iterativo, Cloud SQL intenta encontrar el número de resultados especificado en la cláusula LIMIT, pero no garantiza que se encuentre ese número. Esto puede ocurrir si se alcanza el número máximo de vecinos (cloudsql_vector_iterative_filtering_max_neighbors) antes de que se cumpla LIMIT o si no hay suficientes filas que coincidan con el filtro en la tabla.

  • Consultas complejas: el filtrado iterativo solo funciona cuando los predicados de filtro se insertan en la ruta de acceso de la tabla base. No se admite en filtros de tablas temporales, como las tablas que usan una cláusula HAVING. En las subconsultas, solo se tienen en cuenta los filtros de la tabla base de la propia subconsulta para el filtrado iterativo.

Comprobar el estado de la alternativa en las búsquedas de ANN

En algunos casos, una búsqueda de ANN se convierte en una búsqueda de KNN. Algunos de los cambios no permitidos afectan a estos elementos:

  • No hay ningún índice vectorial en la tabla base.
  • Hay un índice vectorial en la tabla base, pero usa una medida de distancia diferente del parámetro distance_measure en las opciones de búsqueda approx_distance.
  • El índice vectorial está dañado o no es visible para la transacción actual.
  • El valor de LIMIT especificado es superior a 10.000.
  • No se ha especificado ningún LIMIT.
  • La consulta actual implica más de una llamada approx_distance en la misma tabla base.
  • El optimizador calcula que es más eficiente usar KNN.

En todos estos casos, se envía una advertencia al cliente indicando que se ha realizado una búsqueda exacta y el motivo.

Usa el siguiente comando en el cliente de MySQL para ver el estado de la alternativa:

SHOW global status LIKE '%cloudsql_vector_knn_fallback%';

Si quieres usar ANN y se vuelve a KNN, es posible que la consulta se ejecute más lentamente. Deberías averiguar por qué se está usando la alternativa y evaluar si debes hacer cambios para que se utilice la red neuronal artificial.

Ejemplo: Crear un índice vectorial y ejecutar una consulta ANN

En el siguiente ejemplo se muestran los pasos para crear un índice vectorial y ejecutar una consulta ANN en Cloud SQL.

  1. Generar incrustaciones de vectores. Puedes crear inserciones vectoriales manualmente o usar la API de inserciones de texto que prefieras. Para ver un ejemplo que usa Vertex AI, consulta Generar inserciones de vectores basadas en datos de filas.
  2. Crea una tabla en Cloud SQL que contenga una columna de inserción de vector con tres dimensiones.

    CREATE TABLE books(
    id INTEGER PRIMARY KEY AUTO_INCREMENT, title VARCHAR(60), embedding VECTOR(3) USING VARBINARY);
    
  3. Inserta una inserción de vector en la columna.

    INSERT INTO books VALUES ((1, 'book title', string_to_vector('[1,2,3]')));
    
  4. Confirma los cambios.

    commit;
    
  5. Crea el índice vectorial con la función L2_squared para medir la distancia.

    CREATE
      VECTOR INDEX vectorIndex
    ON dbname.books(embeddings)
    USING SCANN QUANTIZER = SQ8 DISTANCE_MEASURE = l2_squared;
    
  6. Usa la siguiente sintaxis para realizar una búsqueda de ANN con un LIMIT de 4 resultados de búsqueda:

    SELECT title
    FROM books
    ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
    LIMIT 4;
    
    SELECT approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=cosine') dist
    FROM books
    ORDER BY dist
    LIMIT 4;
    

Búsqueda de los k vecinos más cercanos (KNN)

Para realizar una búsqueda de los k vecinos más cercanos, usa la función vector_distance con una opción de medida de distancia y una función de conversión de vectores (string_to_vector o vector_to_string) en una instrucción SELECT. Utilice la siguiente sintaxis:

SELECT vector_distance(string_to_vector('[1,2,3]'),
                      string_to_vector('[1,2,3]'),
                      'Distance_Measure=dot_product');

Sustituye los valores [1,2,3] por los valores de inserción de tus datos.

En el siguiente ejemplo se muestra cómo usar esta consulta con la función cosine_distance y la función de conversión de vectores string_to_vector.

SELECT id,cosine_distance(embedding, string_to_vector('[1,2,3]')) dist
FROM books
ORDER BY distance
LIMIT 10;

Obtener la distancia del coseno en una consulta KNN

Usa la función cosine_distancede Cloud SQL para calcular la distancia mediante el coseno.

SELECT cosine_distance(embedding, string_to_vector('[3,1,2]')) AS distance FROM books WHERE id = 10;

Obtener la distancia del producto escalar en una consulta de KNN

Usa la función dot_product de Cloud SQL para calcular la distancia mediante el producto escalar.

SELECT dot_product(embedding, string_to_vector('[3,1,2]')) AS distance FROM books WHERE id = 10;

Obtener la distancia al cuadrado L2 en una consulta KNN

Usa la función Cloud SQL l2_squared_distance para calcular la distancia con la norma L2 al cuadrado.

SELECT
  l2_squared_distance(embedding, string_to_vector('[3,1,2]'))
    AS distance
FROM books
WHERE id = 10;

Siguientes pasos