Pesquisar e filtrar com embeddings de vetor

Esta página descreve as diferentes maneiras de consultar embeddings de vetor. Para uma visão geral das pesquisas de similaridade de ANN e KNN, consulte Pesquisas de vetor.

Antes de começar

Ative a flag de banco de dados cloudsql_vector na instância do Cloud SQL.

Para instâncias que usam o Cloud SQL para MySQL 9.7 ou mais recente, embora não seja necessário ativar o cloudsql_vector para criar e armazenar embeddings de vetor, é preciso ativar a flag de banco de dados cloudsql_vector na instância do Cloud SQL para criar índices de vetor e realizar pesquisas de ANN nos dados de vetor.

Pesquisar vizinhos mais próximos aproximados (ANN)

Para realizar uma pesquisa de ANN, use a approx_distance função em uma SELECT e ORDER BY cláusula. É necessário usar uma cláusula LIMIT em uma pesquisa de ANN. Também é possível receber o valor da distância colocando approx_distance em uma lista SELECT.

Use a seguinte sintaxe para 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;

A função approx_distance usa as seguintes opções:

  • embedding: usa o nome da coluna de embedding de vetor da tabela base.
  • string_to_vector ou vector_to_string: converte um vetor em uma string e uma string em um vetor para tornar o vetor legível.
  • distance_measure: especifica a medida de distância a ser usada para uma pesquisa de similaridade de vetor. Esse valor precisa corresponder ao valor definido no parâmetro distance_measure ao criar o índice. Esse parâmetro é obrigatório. Os valores possíveis para esse parâmetro são:
    • COSINE
    • L2_SQUARED
    • DOT_PRODUCT
  • num_leaves_to_search: opcional. Especifica o número de folhas a serem testadas para uma pesquisa de similaridade de vetor ANN. Se você não especificar o número de folhas, o Cloud SQL usará um valor gerado com base no tamanho da tabela, no número de folhas no índice de vetor e em outros fatores. É possível conferir esse valor em information_schema.innodb_vector_indexes. Recomendamos ajustar num_leaves_to_search para alcançar o melhor equilíbrio entre qualidade e desempenho da pesquisa para sua carga de trabalho específica. Se aumentado, ele afeta o desempenho, mas melhora a recuperação.

O exemplo a seguir mostra como usar approx_distance para encontrar as K linhas mais próximas usando a medida de distância l2_squared e ordenar os resultados por distância.

# 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 approx_distance

É possível usar a função approx_distance com condições WHERE que filtram os resultados da consulta com um predicado não vetorial para realizar a pós-filtragem. A função approx_distance é avaliada antes da aplicação do filtro, o que significa que o número de resultados retornados é não determinístico.

Por exemplo, para a seguinte consulta:

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

A função approx_distance retorna os 11 vizinhos mais próximos do vetor de consulta, independentemente do preço. Na pós-filtragem, os produtos com um preço < 100 são selecionados. É possível que todos os vizinhos mais próximos tenham um preço < 100, então há 11 resultados para a consulta. Como alternativa, se nenhum dos vizinhos mais próximos tiver um preço < 100, nenhuma linha será retornada.

Se você prevê que o filtro na condição WHERE é muito seletivo, uma pesquisa exata (KNN) é uma opção para garantir que um número suficiente de linhas seja retornado.

Outra opção é usar a filtragem iterativa para verificar mais do índice de pesquisa de ANN.

Usar a filtragem iterativa para aumentar os resultados da pesquisa de ANN

É possível usar a filtragem iterativa quando os filtros seletivos da cláusula WHERE na consulta de pesquisa de ANN produzem menos resultados do que o número especificado na cláusula LIMIT.

Por exemplo, na consulta a seguir, ao ativar a filtragem iterativa, a consulta verifica mais do índice de vetor, menos o primeiro 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)

Você busca mais vizinhos do índice de vetor de pesquisa de forma iterativa até que o máximo configurado (cloudsql_vector_iterative_filtering_max_neighbors) seja atingido. Todas as correspondências de filtro são contadas para o LIMIT e removidas das verificações adicionais do índice de vetor.

Ativar a filtragem iterativa

Por padrão, a filtragem iterativa está desativada para todas as sessões e instâncias do Cloud SQL.

Para ativar a filtragem iterativa para uma sessão atual, use a seguinte instrução SQL.

SET SESSION cloudsql_vector_iterative_filtering=on;

Também é possível ativar a filtragem iterativa globalmente para todas as sessões de cliente que se conectam à instância definindo a flag na instância. Para definir uma flag para uma instância, consulte Definir uma flag de banco de dados.

Para mais informações sobre como definir variáveis de sistema no nível da sessão ou global, consulte Usar variáveis de sistema na documentação do MySQL.

Ajustar a filtragem iterativa

Para controlar quantos vizinhos mais próximos são retornados para uma consulta de pesquisa de ANN com a filtragem iterativa ativada, é possível usar a variável de sistema global ou de sessão cloudsql_vector_iterative_filtering_max_neighbors. É possível usar essa configuração para aumentar o número de vizinhos mais próximos solicitados. No entanto, para evitar o armazenamento de muitos resultados na memória, o máximo para essa variável é 1000.

Para definir essa variável para uma sessão, use a seguinte instrução SQL:

SET cloudsql_vector_iterative_filtering_max_neighbors=600;

O padrão é 500, e o número mínimo é 10.

Limitações

Confira a seguir as limitações do uso da filtragem iterativa:

  • Não é uma garantia: ao usar a filtragem iterativa, o Cloud SQL tenta encontrar o número de resultados especificado na cláusula LIMIT, mas não garante que o número seja encontrado. Isso pode acontecer se o número máximo de vizinhos (cloudsql_vector_iterative_filtering_max_neighbors) for atingido antes que o LIMIT seja atendido ou se não houver linhas suficientes que correspondam ao filtro na tabela.

  • Consultas complexas: a filtragem iterativa funciona apenas quando os predicados de filtro são enviados para o caminho de acesso da tabela de base. Ela não é compatível com filtros em tabelas temporárias, por exemplo, tabelas que usam uma cláusula HAVING. Em subconsultas, apenas os filtros na tabela de base dentro da própria subconsulta são considerados para filtragem iterativa.

Verificar o status de fallback em pesquisas de ANN

Há alguns casos em que uma pesquisa de ANN volta para uma pesquisa de KNN. Estes incluem o seguinte:

  • Não há índice de vetor na tabela base.
  • Há um índice de vetor na tabela base, mas ele usa uma medida de distância diferente do parâmetro distance_measure nas opções de pesquisa approx_distance.
  • O índice de vetor está corrompido ou invisível para a transação atual.
  • O LIMIT especificado é maior que 10.000.
  • Não há LIMIT especificado.
  • A consulta atual envolve mais de uma chamada approx_distance na mesma tabela de base.
  • O otimizador calcula que é mais eficiente usar o KNN.

Todos esses casos enviam um aviso ao cliente indicando que a pesquisa exata foi realizada e o motivo.

Use o comando a seguir no cliente mysql para conferir o status de fallback:

SHOW global status LIKE '%cloudsql_vector_knn_fallback%';

Se você quiser usar o ANN e ele estiver voltando para o KNN, a consulta poderá ser executada mais lentamente. Encontre o motivo do fallback e avalie se é necessário fazer mudanças para que o ANN seja usado.

Exemplo: criar um índice de vetor e executar uma consulta de ANN

O tutorial de exemplo a seguir apresenta etapas para criar um índice de vetor e executar uma consulta de ANN no Cloud SQL.

  1. Gerar embeddings de vetor. É possível criar embeddings de vetor manualmente ou usar uma API de embedding de texto de sua preferência. Para conferir um exemplo que usa Vertex AI, consulte Gerar embeddings de vetor com base em dados de linha.
  2. Crie uma tabela no Cloud SQL que contenha uma coluna de embeddings de vetor com três dimensões.

    CREATE TABLE books(
    id INTEGER PRIMARY KEY AUTO_INCREMENT, title VARCHAR(60), embedding VECTOR(3) USING VARBINARY);
    
  3. Insira um embedding de vetor na coluna.

    INSERT INTO books VALUES ((1, 'book title', string_to_vector('[1,2,3]')));
    
  4. Faça commit das alterações.

    commit;
    
  5. Crie o índice de vetor usando a função L2_squared para medir a distância.

    CREATE
      VECTOR INDEX vectorIndex
    ON dbname.books(embeddings)
    USING SCANN QUANTIZER = SQ8 DISTANCE_MEASURE = l2_squared;
    
  6. Use a seguinte sintaxe para realizar uma pesquisa de ANN com um LIMIT de 4 resultados de pesquisa:

    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;
    

Pesquisar vizinhos k-mais próximos (KNN)

Para realizar uma pesquisa de vizinho k-mais próximo, use a vector_distance função com uma opção de medida de distância e uma função de conversão de vetor (string_to_vector ou vector_to_string) em uma instrução SELECT. Use a seguinte sintaxe:

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

Substitua os valores [1,2,3] pelos valores de embedding dos seus dados.

O exemplo a seguir mostra como usar essa consulta com a função cosine_distance e a função de conversão de vetor string_to_vector.

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

Encontrar a distância do cosseno em uma consulta de KNN

Use a função cosine_distance do Cloud SQL para calcular a distância usando o cosseno.

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

Encontrar a distância do produto escalar em uma consulta de KNN

Use a função dot_product do Cloud SQL para calcular a distância usando o produto escalar.

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

Encontrar a distância de L2 ao quadrado em uma consulta de KNN

Use a função l2_squared_distance do Cloud SQL para calcular a distância usando L2 ao quadrado.

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

A seguir