Trabalhar com embeddings vetoriais

Nesta página, você verá como interagir com o Cloud SQL para criar aplicativos que usam embeddings de vetor.

O Cloud SQL para MySQL é compatível com o armazenamento de embeddings de vetor. É possível então criar índices de pesquisa de vetor e fazer pesquisas por similaridade nesses embeddings de vetor com o restante dos dados armazenados no Cloud SQL.

Armazenamento de embeddings de vetor

Use o Cloud SQL para MySQL para armazenar embeddings de vetor criando uma coluna de embeddings de vetor em uma tabela. A coluna de embeddings de vetor especiais é mapeada com o tipo de dados VARBINARY. Assim como outros dados relacionais na tabela, é possível acessar embeddings de vetor na tabela com garantias transacionais existentes. Uma tabela com uma coluna de embeddings de vetor é uma tabela normal do InnoDB e, portanto, é compatível com propriedades de atomicidade, consistência, isolamento e durabilidade (ACID). As propriedades ACID divergem apenas em relação a buscas de índices de pesquisa de vetor.

É possível criar uma só coluna de embeddings de vetor em uma tabela e um só índice de pesquisa de vetor para cada tabela. Cada embedding de vetor armazenado na mesma coluna precisa ter exatamente as mesmas dimensões que você especificou quando definiu a coluna. Um embedding de vetor tem um limite superior de 16.000 dimensões. Se você tiver armazenamento e memória suficientes disponíveis, será possível ter tabelas separadas com diferentes colunas de embeddings de vetor e índices de pesquisa de vetor na mesma instância.

Não há um limite absoluto para o número de embeddings de vetor que podem ser armazenados em uma tabela, mas os índices de pesquisa de vetor exigem memória. Por esse motivo, recomendamos não armazenar mais de 10 milhões de embeddings de vetor em uma tabela.

A replicação funciona da mesma maneira para a coluna de embeddings de vetor e para outras colunas do MySQL InnoDB.

O Cloud SQL é compatível com a pesquisa por similaridade que usa consultas de pesquisa de vizinho k-mais perto (KNN, na sigla em inglês) e de vizinho aproximado mais perto (ANN, na sigla em inglês). É possível usar os dois tipos de pesquisas de vetor nas instâncias do Cloud SQL. É possível criar um índice de pesquisa de vetor para pesquisas de ANN.

O Cloud SQL permite consultas que usam pesquisa de vetor KNN, também chamada de pesquisa de vizinho exato mais perto. A execução de uma pesquisa de vetor KNN fornece recall perfeito. É possível realizar pesquisas de KNN sem precisar criar um índice de pesquisa de vetor. A pesquisa de KNN é baseada na execução de um algoritmo de verificação de tabela.

Para a pesquisa de KNN, o Cloud SQL também é compatível com as seguintes funções de pesquisa de distância de vetor:

  • Cosseno
  • Produto escalar
  • Distância de L2 ao quadrado

Para mais informações sobre como usar funções de distância na pesquisa de vetor, consulte Consultar a distância de um embedding de vetor.

O Cloud SQL permite criar e consultar pesquisas de ANN pela criação de índices de pesquisa de vetor. Um índice de pesquisa de vetor ANN permite otimização para um desempenho rápido no lugar de um recall perfeito. Para a pesquisa de ANN, o Cloud SQL aceita os seguintes tipos de índice:

  • BRUTE_FORCE: o tipo de índice de pesquisa de vetor padrão para uma tabela base com menos de 10.000 linhas. Esse tipo é mais adequado para pesquisas em um subconjunto menor de um conjunto de dados original. A memória usada pelo índice é igual ao tamanho do conjunto de dados. Esse tipo de índice não permanece no disco.
  • TREE_SQ: o tipo de índice de pesquisa de vetor padrão para uma tabela base com 10.000 linhas ou mais. Esse tipo usa a menor quantidade de memória ou aproximadamente 25% do tamanho do conjunto de dados. Os índices TREE_SQ permanecem no disco.
  • TREE_AH: um tipo de índice de pesquisa de vetor que fornece um algoritmo de tipo de pesquisa de hash assimétrico. Conforme implementado no Cloud SQL, esse tipo de índice não é otimizado para o consumo de memória e não é permanente.

Atualizar índices de pesquisa de vetor

O Cloud SQL para MySQL atualiza índices de pesquisa de vetor em tempo real. Qualquer transação que realiza operações de linguagem de manipulação de dados (DML, na sigla em inglês) na tabela base também propaga alterações nos índices de pesquisa de vetor associados. As alterações em um índice de pesquisa de vetor ficam visíveis imediatamente para todas as outras transações, o que significa um nível de isolamento READ_UNCOMMITTED.

Se você reverter uma transação, as alterações de reversão correspondentes também ocorrerão no índice de pesquisa de vetor.

Replicação de índices de pesquisa de vetor

O Cloud SQL para MySQL replica os índices de pesquisa de vetor em todas as réplicas de leitura. Os filtros de replicação e a replicação de índices de pesquisa de vetor para réplicas em cascata não são compatíveis.

Configurar uma instância para permitir embeddings de vetor

Nesta seção, descrevemos como configurar sua instância do Cloud SQL para permitir o armazenamento, a indexação e a consulta de embeddings de vetor.

As instâncias do Cloud SQL edição Enterprise e Cloud SQL edição Enterprise Plus são compatíveis com embeddings de vetor.

Antes de começar

  • A instância precisa estar em execução no Cloud SQL para MySQL versão 8.0.36.R20240401.03_00 ou mais recente.
  • A instância precisa ter espaço em disco e memória suficientes para alocar memória ao número total de embeddings de vetor na instância.

Ativar suporte a embeddings de vetor

Para ativar o suporte a embeddings de vetor, é preciso configurar as flags do banco de dados MySQL.

gcloud sql instances patch INSTANCE_NAME \
  --database-flags=FLAGS

Substitua INSTANCE_NAME pelo nome da instância em que você quer ativar o suporte a embeddings de vetor.

Em FLAGS, configure as seguintes flags do MySQL na sua instância:

  • cloudsql_vector: defina essa flag como on para ativar o suporte a armazenamento e pesquisa de embeddings de vetor. É possível criar novas colunas de embeddings de vetor e índices de pesquisa de vetor na instância.
  • cloudsql_vector_max_mem_size: opcional. Especifique a alocação máxima de memória em bytes para todos os índices de pesquisa de vetor na instância. Se você não especificar essa flag, a alocação de memória padrão será de 1 GB, que é a alocação de memória mínima. Para mais informações sobre como calcular o valor a ser especificado, consulte Configurar a alocação de memória para índices de pesquisa de vetor.

    Essa memória dedicada vem da memória alocada para o innodb_buffer_pool_size. Seu pool de buffer disponível é reduzido na mesma quantidade. O valor máximo permitido para essa flag é 50% do innodb_buffer_pool_size total.

    Se você especificar um valor maior que 50% do innodb_buffer_pool_size total, o Cloud SQL reduzirá o valor efetivo a 50% do tamanho disponível e registrará uma mensagem de aviso para a instância.

Depois de configurar as flags, o comando ficará assim:

gcloud sql instances patch my-instance \
  --database-flags=cloudsql_vector=on,cloudsql_vector_max_mem_size=4294967296

As flags para configurar o suporte a embeddings de vetor no Cloud SQL para MySQL são estáticas. Depois de atualizar a instância com as flags, ela será reiniciada automaticamente para que as alterações de configuração entrem em vigor.

Para mais informações sobre como configurar flags de banco de dados para o MySQL, consulte Configurar flags de banco de dados.

Desativar suporte a embeddings de vetor

Para desativar o suporte a embeddings de vetor, defina a flag cloudsql_vector como off.

Exemplo:

gcloud sql instances patch INSTANCE_NAME \
  --database-flags=cloudsql_vector=off

Substitua INSTANCE_NAME pelo nome da instância em que você está desativando o suporte a embeddings de vetor.

Definir cloudsql_vector como off impede que você crie novas colunas de embeddings de vetor e índices de pesquisa de vetor. Depois de configurar essa flag estática, a instância é reiniciada automaticamente para que a mudança na configuração entre em vigor.

Após a reinicialização da instância, o Cloud SQL para MySQL faz isto:

  • Remove do disco permanente todos os índices de pesquisa de vetor TREE_SQ mantidos.
  • Mantém as entradas da tabela do dicionário de dados para os índices de pesquisa de vetor que foram criados. No entanto, o Cloud SQL para MySQL não recria os índices, e todas as consultas de pesquisa para esses índices retornam um erro.
  • Continua a armazenar os embeddings de vetor nas tabelas base. Os embeddings de vetor permanecem acessíveis.

Se mais tarde você reativar a flag cloudsql_vector da instância, o Cloud SQL tentará recriar os índices enquanto a instância é reiniciada com base nas entradas da tabela do dicionário de dados.

Configurar a alocação de memória para índices de pesquisa de vetor

O Cloud SQL cria e mantém índices de pesquisa de vetor na memória. O tipo de índice TREE_SQ permanece em um encerramento limpo e é recarregado após a reinicialização da instância. Durante o tempo de execução, todos os índices de pesquisa de vetor precisam permanecer na memória.

Para garantir que o Cloud SQL tenha memória suficiente disponível para manter todos os índices de pesquisa de vetor na memória, configure a instância do Cloud SQL com uma flag de banco de dados cloudsql_vector_max_mem_size. O cloudsql_vector_max_mem_size controla quanta memória a instância do Cloud SQL dedica a índices de pesquisa de vetor. Ao configurar o valor da flag, lembre-se disto:

  • O valor padrão e mínimo é 1 GB. O limite superior é de 50% do tamanho do pool de buffer.
  • Depois de definir essa flag, a instância é reiniciada automaticamente para que a mudança na configuração entre em vigor.
  • Se a instância tiver usado toda a memória configurada, não será possível criar ou alterar índices de pesquisa de vetor.

Para atualizar a memória alocada para índices de pesquisa de vetor na instância, altere o valor da flag cloudsql_vector_max_mem_size.

gcloud sql instances patch INSTANCE_NAME \
  --database-flags= cloudsql_vector_max_mem_size=NEW_MEMORY_VALUE

Substitua:

  • INSTANCE_NAME: o nome da instância em que você está alterando a alocação de memória.
  • NEW_MEMORY_VALUE: a alocação de memória atualizada, em bytes, para seus índices de pesquisa de vetor.

Essa alteração reinicia a instância automaticamente para que a mudança entre em vigor.

Calcular memória necessária

A quantidade de memória que um índice exige depende do tipo de índice, do número de embeddings de vetor e da dimensionalidade dos embeddings. Há dois requisitos de memória a serem considerados:

  • Memória do tempo de build: a memória necessária durante a criação do índice
  • Memória do índice: a memória que o índice ocupará depois que ele for criado

O tamanho do conjunto de dados de um determinado índice é a memória necessária para ler todos os embeddings de vetor na memória. Como cada dimensão é representada por um ponto flutuante que usa 4 bytes de memória, é possível determinar o dataset_size da seguinte maneira:

dataset_size = <num_embeddings> * (4 * <dimensions>)

Por exemplo, se você tiver 1 milhão de embeddings de 768 dimensões, dataset_size será de 3 GB.

Com base no exemplo anterior, os requisitos de memória para os diferentes tipos de índice são estes:

Tipo de índice Memória do tempo de build Memória do índice
TREE_SQ 4 GB 1 GB
TREE_AH 3,5 GB 3,5 GB
BRUTE_FORCE 3 GB 3 GB

Se você estiver usando índices de pesquisa de vetor TREE_SQ, também precisará considerar a memória necessária para a permanência no tempo de execução. Para a quantidade total de memória na sua configuração, adicione a quantidade de memória do índice usada pelo maior índice de pesquisa de vetor TREE_SQ ativo.

Sempre que a tabela base em que os embeddings de vetor estão armazenados passa por operações DML, o índice de pesquisa de vetor é atualizado em tempo real. Essas atualizações mudam o consumo de memória do índice, que pode ser reduzido ou ampliado dependendo da operação DML. É possível monitorar o consumo de memória de um índice consultando a tabela information_schema.innodb_vector_indexes. Para informações sobre como monitorar o tamanho do índice de pesquisa de vetor, consulte Monitorar índices de pesquisa de vetor.

Configuração da réplica de leitura

Se a instância atender aos critérios de ativação de flags e versões de manutenção, o Cloud SQL será totalmente compatível com embeddings de vetor em uma réplica de leitura.

Se você criar uma réplica de uma instância principal que tenha o suporte a embeddings de vetor ativado, a réplica de leitura herdará da instância principal as configurações desse suporte. É preciso ativar o suporte a embeddings de vetor individualmente em instâncias de réplica de leitura já existentes.

Em termos de impacto no atraso de replicação, a criação e a manutenção de índices de pesquisa de vetor funcionam da mesma maneira que os índices normais do MySQL.

Os índices de pesquisa de vetor não são compatíveis com réplicas em cascata.

Exemplo: um índice de pesquisa de vetor ANN simples e uma consulta

O tutorial de exemplo a seguir apresenta etapas para criar um índice de pesquisa de vetor baseado em ANN e uma consulta 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 a Vertex AI, consulte Gerar embeddings de vetor com base em dados de linha.

  2. Crie uma tabela no Cloud SQL para MySQL que contém 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 pesquisa de vetor. Se você for criar um índice TREE_SQ ou TREE_AH, sua tabela precisará ter pelo menos 1.000 linhas.

    CALL mysql.create_vector_index('vectorIndex',
                                   'dbname.books',
                                   'embedding',
                                   'index_type=BRUTE_FORCE, distance_measure=L2_SQUARED'
                                   );
    
  6. Encontre os vizinhos mais perto.

    SELECT title FROM books
    WHERE
    NEAREST(embedding) TO (string_to_vector('[1,2,3]'));
    

Gere embeddings de vetor com base nos dados das linhas

É possível gerar um embedding de vetor para os dados de uma determinada linha usando uma API de embedding de texto, como a Vertex AI ou a OpenAI. É possível usar qualquer API de embedding de texto com embeddings de vetor do Cloud SQL. No entanto, é necessário usar a mesma API de embedding de texto para gerar vetores de string de consulta. Não é possível combinar diferentes APIs para vetorização de consultas e dados de origem.

Por exemplo, é possível gerar um embedding de vetor pela Vertex AI:

from vertexai.language_models import TextEmbeddingModel

def text_embedding() -> list:
    """Text embedding with a Large Language Model."""
    model = TextEmbeddingModel.from_pretrained("text-embedding-004")
    embeddings = model.get_embeddings(["What is life?"])
    for embedding in embeddings:
        vector = embedding.values
        print(f"Length of Embedding Vector: {len(vector)}")
    return vector

if __name__ == "__main__":
    text_embedding()

Armazenar embeddings de vetores

Nesta seção, você verá exemplos de instruções para armazenar embeddings de vetor no Cloud SQL.

Criar uma nova tabela com uma coluna de embeddings de vetor

CREATE TABLE books (
  id INTEGER PRIMARY KEY AUTO_INCREMENT,
  title VARCHAR(60),
  embedding VECTOR(3) USING VARBINARY
  );

Adicionar uma coluna de embeddings de vetor a uma tabela já existente

ALTER TABLE books
ADD COLUMN embedding
VECTOR(3) USING VARBINARY;

Inserir um embedding de vetor

INSERT INTO books (
  title,
  embedding
  ) VALUES (
    'book title',
    string_to_vector('[1,2,3]')
);

Inserir vários embeddings de vetor

INSERT INTO books (
  title,
  embedding
  ) VALUES (
    'book title',
    string_to_vector('[1,2,3]')),
     ('book title', string_to_vector('[4,5,6]')
);

Fazer upsert de um embedding de vetor

INSERT INTO books (
  id,
  title,
  embedding
  ) VALUES (
    1,
    'book title',
     string_to_vector('[1,2,3]')
     )
ON DUPLICATE KEY UPDATE embedding = string_to_vector('[1,2,3]');

Atualizar um embedding de vetor

UPDATE books
SET embedding = string_to_vector('[1,2,3]')
WHERE id = 1;

Excluir um embedding de vetor

DELETE FROM books
WHERE embedding = string_to_vector('[1,2,3]');

Trabalhar com índices de pesquisa de vetor

Por padrão, é possível realizar a pesquisa de vizinho exato mais perto, o que fornece um recall perfeito. Também é possível adicionar um índice para usar a pesquisa de ANN, que troca certo recall por velocidade. Ao contrário dos índices comuns, depois de adicionar um índice aproximado, você verá resultados diferentes para as consultas.

Recomendações

Nesta seção, você conhecerá práticas recomendadas para trabalhar com índices de pesquisa de vetor. Cada carga de trabalho é diferente, e talvez você precise ajustá-la de acordo.

  • Antes de criar um índice de pesquisa de vetor, carregue os dados na tabela. Sua tabela base precisa ter pelo menos 1.000 linhas. Esses requisitos se aplicam apenas aos tipos de índice de pesquisa TREE_SQ e TREE_AH. Se houver mais pontos de dados disponíveis, você terá um melhor particionamento e treinamento do índice.
  • Monitore o uso da memória dos índices. Se a instância ficar sem memória, não será possível criar índices. Para os índices já existentes, depois de atingir o limite, o Cloud SQL gravará periodicamente avisos no registro de erro do MySQL. Confira o uso da memória na tabela information_schema.innodb_vector_indexes.
  • Se a tabela base subjacente tiver passado por alterações de DML grandes, recrie os índices de pesquisa de vetor. Para ver o tamanho inicial do índice no tempo de build e o tamanho atual do índice, consulte a tabela information_schema.innodb_vector_indexes.
  • Geralmente, é aceitável deixar o número de partições para ser calculado internamente. Se você quiser especificar o número de partições em um caso de uso, tenha pelo menos 100 pontos de dados para cada partição.

Tabela base somente leitura durante operações de índice de pesquisa de vetor

Durante as três operações de índice de pesquisa de vetor (criar, alterar e descartar), a tabela base é colocada em modo somente leitura. Durante essas operações, nenhuma DML é permitida na tabela base.

Permanência, encerramento e impacto na manutenção

Somente os índices de pesquisa de vetor que usam o tipo TREE_SQ permanecem no disco após o encerramento limpo de uma instância. Os índices de pesquisa de vetor que usam os tipos TREE_AH e BRUTE_FORCE são apenas na memória.

Após um encerramento limpo de uma instância, o Cloud SQL recarrega os índices de pesquisa de vetor enquanto a instância é reiniciada. No entanto, após uma falha ou um encerramento incorreto, o Cloud SQL precisa recriar os índices de pesquisa de vetor. Por exemplo, sempre que sua instância passa por uma falha e recuperação de backup e restauração, recuperação pontual (PITR, na sigla em inglês) ou por um failover de alta disponibilidade (HA, na sigla em inglês), o Cloud SQL recria a pesquisa de índices de vetor. Nesses eventos, ocorre isto:

  • A recriação acontece automaticamente em segundo plano.
  • Durante a recriação, a tabela base fica no modo somente leitura.
  • Se a recriação automática não conseguir um bloqueio na tabela dentro de um tempo limite específico, a recriação falhará. Talvez seja necessário recriar o índice manualmente.

O tempo necessário para recriar um índice pode aumentar o tempo de encerramento necessário, o que também pode aumentar o tempo de manutenção e atualização necessário para uma instância.

Criar um índice de pesquisa de vetor

A instrução para criar um índice de pesquisa de vetor usa a seguinte sintaxe:

CALL mysql.create_vector_index('INDEX_NAME',
                                'DB_NAME.TABLE_NAME',
                                'COLUMN_NAME',
                                'PARAMETERS'
                              );

Exemplo:

CALL mysql.create_vector_index('vectorIndex',
                                'db.books',
                                'embedding',
                                'index_type=TREE_SQ, distance_measure=l2_squared'
                               );

O nome do índice especificado precisa ser exclusivo no banco de dados.

Parâmetros de índice de pesquisa de vetor

As funções de criar e alterar índice de pesquisa são compatíveis com vários parâmetros que podem ser especificados com pares de chave-valor separados por vírgulas. Todos os parâmetros da função de criar índice de pesquisa são opcionais. Se você especificar uma string vazia ou NULL, os valores de parâmetro padrão serão configurados para o índice.

  • distance_measure: os valores aceitos são: L2_SQUARED, COSINE e DOT_PRODUCT. O padrão é L2_SQUARED.
  • num_neighbors: o número de vizinhos que será retornado por padrão durante as consultas de ANN. Também é possível modificar esse parâmetro ao executar a consulta de pesquisa. O padrão é 10.
  • index_type: especifica o tipo de índice a ser criado. Os valores válidos são: BRUTE_FORCE, TREE_SQ e TREE_AH.

    • BRUTE_FORCE é o padrão para uma tabela com menos de 10.000 linhas
    • TREE_SQ é o padrão para uma tabela com 10.000 linhas ou mais

    Para especificar o tipo de índice TREE_AH ou TREE_SQ, o tamanho da tabela base precisa ser maior que 1.000 linhas.

  • num_parititions: especifica quantos clusters K-means serão criados. Esse parâmetro só será permitido se você tiver configurado um index_type. Essa opção não se aplica a BRUTE_FORCE. Se você especificar o tipo de índice TREE_SQ ou TREE_AH, o tamanho da tabela base precisará ser maior ou igual a num_partitions * 100.

Alterar um índice de pesquisa de vetor

CALL mysql.alter_vector_index('DB_NAME.INDEX_NAME', 'PARAMETERS');

A função alter_vector_index é usada explicitamente para recriar um índice de pesquisa de vetor. Para usar essa função, o índice precisa já existir. É recomendável recriar um índice para os seguintes casos de uso:

  • Você quer recriar o índice com opções diferentes. Por exemplo, quando você quer usar um tipo de índice ou medida de distância diferente.
  • Você quer recriar o índice porque a tabela base passou por alterações de DML grandes. Por exemplo, você precisa treinar novamente o índice de pesquisa de vetor com base nos dados atuais da tabela base.

Todos os parâmetros para recriar o índice são idênticos àqueles disponíveis para criar o índice e também são opcionais. Se você especificar uma string vazia ou NULL ao recriar o índice, ele será recriado com base nos parâmetros especificados no momento da criação dele. Se nenhum parâmetro for definido no momento da criação do índice, os valores de parâmetro padrão serão usados.

O índice de pesquisa de vetor existente fica disponível durante a operação de alterar. Ainda é possível realizar consultas de pesquisa no índice.

Descartar um índice de pesquisa de vetor

Não é possível executar uma operação DDL em uma tabela que tem um índice de pesquisa de vetor. Antes de executar a operação DDL na tabela, é preciso descartar o índice de pesquisa de vetor.

CALL mysql.drop_vector_index('DB_NAME.INDEX_NAME');

Consultar embeddings de vetor

Nesta seção, apresentamos exemplos das diferentes maneiras de consultar embeddings de vetor.

Ver os embeddings de vetor

SELECT vector_to_string(embedding) FROM books;

Fazer a pesquisa de vizinho exato para um embedding de vetor

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

Fazer a pesquisa de vizinho aproximado para um embedding de vetor

SELECT title FROM books
WHERE
NEAREST(embedding) TO (string_to_vector('[1,2,3]'), 'num_neighbors=10');

A execução de uma pesquisa de ANN aceita dois parâmetros. Ambos são opcionais.

  • num_partitions: especifica o número de partições para sondagem em uma pesquisa de vetor ANN. Se você não especificar o número de partições, a pesquisa usará um valor gerado com base no tamanho da tabela, no número de partições no índice de pesquisa de vetor e em outros fatores.
  • num_neighbors: especifica o número de vizinhos que será retornado. Esse valor substitui aquele definido no momento da criação do índice de pesquisa de vetor.

Filtrar embeddings de vetor

Use colunas extras como predicados para ajustar a filtragem dos resultados da consulta de embeddings de vetor. Por exemplo, se você adicionar uma coluna printyear, insira um valor de ano específico como filtro na sua consulta.

SELECT title FROM books
WHERE
NEAREST(embedding) TO (string_to_vector('[1,2,3]'))
AND printyear > 1991;

Consultar a distância de um embedding de vetor

Nesta seção, apresentamos exemplos de funções de distância de vetor que estão disponíveis para pesquisa de KNN.

Encontrar a distância do 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

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

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

Encontrar linhas em uma determinada distância

SELECT * FROM books
WHERE l2_squared_distance(embedding, string_to_vector('[1,2,3]')) < 10;

É possível combinar com ORDER BY e LIMIT

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

Monitorar índices de pesquisa de vetor

Para receber informações em tempo real sobre todos os índices de pesquisa de vetor na instância, use a tabela information_schema.innodb_vector_indexes.

Para ver a tabela, execute o seguinte comando:

SELECT * FROM information_schema.innodb_vector_indexes;

O exemplo de resultado será assim:

*************************** 1. row ***************************
       INDEX_NAME: test.t4_index
       TABLE_NAME: test.t4_bf
       INDEX_TYPE: BRUTE_FORCE
     DIST_MEASURE: SquaredL2Distance
           STATUS: Ready
            STATE: INDEX_READY_TO_USE
       PARTITIONS: 0
SEARCH_PARTITIONS: 0
     INITIAL_SIZE: 40000
     CURRENT_SIZE: 40000
          QUERIES: 0
        MUTATIONS: 0
     INDEX_MEMORY: 160000
   DATASET_MEMORY: 0

Na tabela information_schema.innodb_vector_indexes, é possível ver isto:

  • As opções que podem ser geradas. Em outras palavras, num_partitions ou o número de partições para sondagem em uma consulta.
  • As colunas STATE e STATUS informam o estado atual do índice. Durante a fase de criação, a coluna de status mostra informações sobre até que ponto o índice de pesquisa de vetor está na fase de criação.
  • A coluna INITIAL_SIZE mostra o tamanho da tabela durante a criação do índice. É possível comparar esse tamanho com CURRENT_SIZE para ter uma ideia de quanto o índice mudou desde a criação devido a DMLs na tabela base.
  • As colunas QUERIES e MUTATIONS mostram insights em tempo real sobre a ocupação do índice.
  • As colunas INDEX_MEMORY e DATASET_MEMORY mostram informações sobre o consumo de memória do índice. INDEX_MEMORY

    indica quanta memória é consumida pelo índice, e DATASET_MEMORY indica quanta memória extra é consumida durante o tempo de build.

Para ver uma lista dos índices de pesquisa de vetor criados na instância, veja a tabela de dicionário de dados mysql.vector_indexes.

Para ver a tabela, execute o seguinte comando:

SELECT * FROM mysql.vector_indexes;

Exemplo de resposta:

*************************** 1. row ***************************
   index_name: test.index1
   table_name: test.t1
  column_name: j
index_options: index_type=BRUTE_FORCE, distance_measure=L2_SQUARED
       status: ACTIVE
  create_time: 2024-04-08 22:46:21
  update_time: 2024-04-08 22:46:21
1 row in set (0.00 sec)

Limitações

  1. Só pode haver uma coluna de embeddings de vetor para cada tabela.
  2. Só pode haver um índice de pesquisa de vetor para cada tabela.
  3. Um embedding de vetor pode ter até 16.000 dimensões.
  4. Não é possível o particionamento no nível da tabela do InnoDB em tabelas com colunas de embeddings de vetor.
  5. Se a instância for reiniciada após um encerramento incorreto, o Cloud SQL recriará automaticamente o índice de pesquisa de vetor.
    1. Ao recriar o índice de pesquisa de vetor, a tabela base será somente leitura.
    2. Se o Cloud SQL não conseguir um bloqueio na tabela no tempo especificado, a recriação automática do índice poderá falhar.
    3. Se a recriação automática do índice falhar, você precisará recriá-lo manualmente.
  6. Para adicionar uma coluna de embeddings de vetor, a tabela precisa ter uma chave primária. O Cloud SQL não é compatível com chaves primárias do tipo BIT, BINARY, VARBINARY, JSON, BLOB, TEXT ou tipos de dados espaciais. Chaves primárias compostas não podem conter qualquer um desses tipos.
  7. Se uma tabela tiver um índice de pesquisa de vetor, as operações DDL não serão permitidas. É preciso descartar o índice de pesquisa de vetor antes de executar operações DDL na tabela base.
  8. Embeddings de vetor não são compatíveis com tabelas que não sejam do InnoDB ou em tabelas temporárias.
  9. A coluna de embeddings de vetor não pode ser uma coluna gerada.
  10. O predicado NEAREST..TO pode ser combinado com outros predicados "escalares" usando AND ou OR. Os predicados escalares na tabela são avaliados após a aplicação dos predicados vetoriais.
  11. O predicado NEAREST..TO é aceito apenas em uma instrução SELECT. Outras instruções DML não aceitam NEAREST..TO.
  12. As subconsultas não são compatíveis com NEAREST..TO. Não será possível adicionar uma restrição à chave primária da tabela base se um índice de pesquisa de vetor estiver presente.
  13. A pré-filtragem só é possível via funções de distância e usando ORDER BY com LIMIT.

    Por exemplo, se você criar a tabela a seguir:

    CREATE TABLE books
    (
    bookid          INT PRIMARY KEY,
    title           VARCHAR(1000),
    author          VARCHAR(100),
    printyear       int,
    country         VARCHAR(100),
    bvector         VECTOR(1536) USING VARBINARY
    //bvector is embedding vector of book's plot,genre,reviews etc
    );

    Use a consulta abaixo para conseguir a pré-filtragem.

    //select query to obtain books by specific author and having similar plot-genre-reviews
    SELECT bookid, title, author,l2_squared_distance(bvector, qvector) dist
    FROM books where author='cloudsql' ORDER BY dist LIMIT 10

    A pós-filtragem é compatível com NEAREST..TO e funções de distância.

Resolver problemas

Caso ocorra uma falha, o índice será recriado automaticamente. Quando uma recriação está em andamento, há duas restrições:

  1. Durante a criação do índice, a tabela base fica no modo somente leitura.
  2. Enquanto o índice é recriado, as consultas de ANN em índices existentes falham.

A seguir