O PolarDB for MySQL oferece suporte à busca por similaridade vetorial via SQL, utilizando um tipo de dado vetorial nativo, funções de distância e índices vetoriais. A computação vetorial ocorre dentro do kernel do banco de dados, com suporte a transações ACID, e utiliza o In-Memory Column Index (IMCI) com algoritmos baseados em HNSW para fornecer tanto a busca exata de k-vizinhos mais próximos (KNN) com 100% de recall quanto a busca aproximada de vizinhos mais próximos (ANN) de alto desempenho.
Os casos de uso comuns incluem sistemas de recomendação, chatbots e recuperação de imagens.
Pré-requisitos
Antes de começar, verifique se você possui:
Um cluster PolarDB for MySQL com versão de kernel 8.0.2, revisão 8.0.2.2.30 ou posterior
Um nó somente leitura IMCI adicionado ao cluster (obrigatório para índices vetoriais)
Histórico de versões
Os recursos variam conforme a versão do kernel. Atualize seu cluster para a versão mais recente para acessar todos os recursos.
|
Recurso |
Versão mínima |
Descrição |
|
Recursos vetoriais básicos e algoritmo de índice HNSW |
8.0.2.2.30 |
Capacidades principais de recuperação vetorial |
|
Algoritmos de índice |
8.0.2.2.31 |
Algoritmos de índice adicionais baseados na biblioteca FAISS |
|
Modificar ou excluir índices vetoriais |
8.0.2.2.32 |
Gerencie índices vetoriais dinamicamente usando |
Início rápido
As etapas a seguir orientam você na criação de uma tabela com índice vetorial, na inserção de dados e na execução de uma busca ANN.
Etapa 1: Configure a tabela.
-- Enable columnstore for the entire table and define a vector index on the v1 column
CREATE TABLE t1 (
id INT PRIMARY KEY,
v1 VECTOR(4) COMMENT 'imci_vector_index=HNSW(metric=COSINE, max_degree=16)'
) COMMENT 'COLUMNAR=1';
Etapa 2: Insira vetores.
INSERT INTO t1 (id, v1) VALUES
(1, STRING_TO_VECTOR('[1.0, 2.0, 3.0, 4.0]')),
(2, STRING_TO_VECTOR('[2.0, 2.2, 2.4, 2.6]')),
(3, STRING_TO_VECTOR('[8.8, 8.88, 8.888, 8.8888]'));
Etapa 3: Ative a busca ANN e execute uma consulta.
-- Enable vector index acceleration (session-level)
SET imci_enable_vector_search = ON;
SET cost_threshold_for_imci = 0;
-- Find the 2 most similar vectors to the query
SELECT id, VECTOR_TO_STRING(v1)
FROM t1
ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[1.2, 2.3, 3.4, 4.5]'), 'COSINE') ASC
LIMIT 2;
Etapa 4: Confirme o uso do índice.
EXPLAIN SELECT id, VECTOR_TO_STRING(v1)
FROM t1
ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[1.2, 2.3, 3.4, 4.5]'), 'COSINE') ASC
LIMIT 2;
Se o plano de execução contiver Vector Search, o índice vetorial está ativo.
+----+---------------------------+------+--------+--------+---------------------------------------------------------------------------------------+
| ID | Operator | Name | E-Rows | E-Cost | Extra Info |
+----+---------------------------+------+--------+--------+---------------------------------------------------------------------------------------+
| 1 | Select Statement | | | | IMCI Execution Plan (max_dop = 2, max_query_mem = 429496729) |
| 2 | └─Compute Scalar | | 2 | 0.00 | |
| 3 | └─Limit | | 2 | 0.00 | Offset=0 Limit=2 |
| 4 | └─Sort | | 2 | 0.00 | Sort Key: VECTOR_DISTANCE(t1.v1,"[1.200000,2.300000,3.400000,4.500000]","COSINE") ASC |
| 5 | └─Vector Search | t1 | 2 | 0.00 | |
+----+---------------------------+------+--------+--------+---------------------------------------------------------------------------------------+
Tipo vetorial
Definir uma coluna vetorial
Utilize VECTOR(N) em uma instrução CREATE TABLE ou ALTER TABLE para definir uma coluna vetorial, onde N representa o número de dimensões (1–16.383). Cada dimensão é um número de ponto flutuante de precisão simples (4 bytes).
-- Define a 4-dimensional vector column
CREATE TABLE t1 (id INT PRIMARY KEY, v1 VECTOR(4));
Restrições:
Uma coluna vetorial suporta comparação de igualdade apenas com outra coluna vetorial. Não é possível compará-la com outros tipos de dados.
Colunas vetoriais não podem ser chave primária, chave estrangeira, chave única ou chave de partição.
Caso
Nexceda 16.383, o seguinte erro será retornado:Data size (xxx Bytes, xxx dimensions) exceeds VECTOR max (65532 Bytes, 16383 dimensions) for column: 'xxx'
Converter entre formatos de string e binário
O PolarDB fornece duas funções para converter dados vetoriais entre formatos de texto e binário.
STRING_TO_VECTOR — converte uma string para o formato binário interno.
Formato de entrada: números de ponto flutuante separados por vírgulas e delimitados por colchetes, por exemplo
'[1.2, 3.4, 5.6]'.A saída utiliza ordem de bytes little-endian. Por exemplo,
1.0(hex0x3F800000) é armazenado como0000803F.Se o formato de entrada for inválido, o erro
Data cannot be converted to a valid vector: 'xxx'é retornado.
SELECT HEX(STRING_TO_VECTOR('[1,2,3,4]'));
-- Output: 0000803F000000400000404000008040
VECTOR_TO_STRING — converte dados vetoriais binários de volta para uma string legível.
Entrada: dados binários onde cada 4 bytes representam uma dimensão em ordem de bytes little-endian.
Se a entrada for inválida, o erro
Data cannot be converted to a valid vector: ''é retornado.
SELECT VECTOR_TO_STRING(0x0000803F000000400000404000008040);
-- Output: [1.00000e+00,2.00000e+00,3.00000e+00,4.00000e+00]
Trabalhar com dados vetoriais
Adicione uma coluna vetorial a uma tabela existente:
ALTER TABLE t1 ADD COLUMN v1 VECTOR(4);
Insira um vetor:
-- As a string using STRING_TO_VECTOR
INSERT INTO t1 (id, v1) VALUES (1, STRING_TO_VECTOR('[1.0, 2.0, 3.0, 4.0]'));
-- In binary format directly
INSERT INTO t1 VALUES (2, 0x0000803F000000400000404000008040);
Faça upsert de um vetor:
INSERT INTO t1 VALUES (1, STRING_TO_VECTOR('[1.0, 2.0, 3.0, 4.0]'))
ON DUPLICATE KEY UPDATE v1 = STRING_TO_VECTOR('[1.0, 2.0, 3.0, 4.0]');
Atualize um vetor:
UPDATE t1 SET v1 = STRING_TO_VECTOR('[1.0, 2.0, 3.0, 4.0]') WHERE id = 1;
Exclua uma linha pelo valor do vetor:
DELETE FROM t1 WHERE v1 = STRING_TO_VECTOR('[1.0, 2.0, 3.0, 4.0]');
Visualize valores vetoriais como strings:
SELECT VECTOR_TO_STRING(v1) FROM t1;
Índices vetoriais
Índices vetoriais são definidos no COMMENT da coluna vetorial. Apenas nós somente leitura IMCI constroem e servem índices vetoriais.
Criar um índice vetorial
Defina um índice vetorial configurando o COMMENT da coluna em uma instrução CREATE TABLE ou ALTER TABLE.
Sintaxe:
COMMENT 'imci_vector_index=<algorithm>(<parameters>) [other_comments]'
imci_vector_index=é um prefixo fixo que declara o índice vetorial.Sempre inclua parênteses após o nome do algoritmo, mesmo ao usar todos os padrões:
HNSW().Separe múltiplos parâmetros com vírgulas.
Cada parâmetro usa o formato
name=valueouname:value.
Algoritmos de índice:
|
Algoritmo |
Implementação |
Características |
|
|
Alta precisão; maior uso de memória |
|
|
|
Alta precisão; maior uso de memória |
|
|
|
Usa quantização de produto (PQ) para compactar vetores — menor uso de memória, alguma perda de precisão |
Parâmetros de construção do índice:
Todos os três algoritmos compartilham os seguintes parâmetros de tempo de construção:
|
Parâmetro |
Alias |
Descrição |
Intervalo |
Padrão |
|
|
|
Medida de similaridade vetorial. Apenas valores em maiúsculas são aceitos. |
|
|
|
|
|
Conexões máximas por nó no grafo. Um valor maior cria um grafo mais denso — construção mais lenta, mas pode melhorar a precisão. |
Inteiro positivo; recomendado 16–64 |
|
|
|
— |
Vizinhos candidatos a avaliar durante a construção do índice. Um valor maior melhora a qualidade do índice, mas aumenta o tempo de construção. |
Inteiro positivo; recomendado 100–500 |
|
O FAISS_HNSW_PQ possui dois parâmetros adicionais para controlar a quantização de produto:
|
Parâmetro |
Descrição |
Intervalo |
Padrão |
|
|
Número de subespaços PQ. Deve ser um divisor da dimensão do vetor. Um valor maior melhora a precisão, mas aumenta o uso de memória. |
Inteiro positivo que divide a dimensão do vetor |
|
|
|
Bits usados para a representação quantizada de cada subespaço. Geralmente definido como 8, o que resulta em 256 centroides por subespaço. |
Inteiro positivo ≤ 24 |
|
Exemplo 1: Defina um índice vetorial ao criar uma tabela.
-- Method 1: Enable columnstore for the entire table
CREATE TABLE t1 (
id INT PRIMARY KEY,
v1 VECTOR(4) COMMENT 'imci_vector_index=HNSW(metric=COSINE, max_degree=16)'
) COMMENT 'COLUMNAR=1';
-- Method 2: Enable columnstore only for the vector column
CREATE TABLE t1 (
id INT PRIMARY KEY,
description TEXT,
v1 VECTOR(4) COMMENT 'COLUMNAR=1, imci_vector_index=HNSW(metric=COSINE)'
);
Exemplo 2: Adicione um índice vetorial a uma tabela existente.
-- Method 1: Enable table-level columnstore and define the vector index in the same statement
ALTER TABLE t1
COMMENT "COLUMNAR=1",
MODIFY COLUMN v1 VECTOR(4) COMMENT "imci_vector_index=HNSW(metric=COSINE,max_degree=16,ef_construction=300)";
-- Method 2: Enable columnstore only for the vector column
-- The vector index is created automatically based on the column COMMENT
ALTER TABLE t1 MODIFY COLUMN v1 VECTOR(4)
COMMENT "COLUMNAR=1 imci_vector_index=HNSW(metric=COSINE,max_degree=16,ef_construction=300)";
Modificar um índice vetorial
Requer a versão 8.0.2.2.32 ou posterior.
Altere o algoritmo ou os parâmetros do índice modificando o COMMENT da coluna.
-- Change the algorithm from HNSW to FAISS_HNSW_FLAT
ALTER TABLE t1 MODIFY COLUMN v1 VECTOR(4)
COMMENT "imci_vector_index=FAISS_HNSW_FLAT(metric=COSINE,max_degree=16,ef_construction=300)";
-- Change max_degree from 16 to 32
ALTER TABLE t1 MODIFY COLUMN v1 VECTOR(4)
COMMENT "imci_vector_index=HNSW(metric=COSINE,max_degree=32,ef_construction=300)";
Excluir um índice vetorial
Exclua o índice vetorial junto com o índice columnstore:
Um índice vetorial não pode existir independentemente de um índice columnstore. Desativar o columnstore exclui o índice vetorial em cascata.
ALTER TABLE t1 COMMENT 'COLUMNAR=0';
Exclua apenas o índice vetorial (requer a versão 8.0.2.2.32 ou posterior):
Limpe o COMMENT da coluna para remover o índice vetorial mantendo o índice columnstore.
ALTER TABLE t1 MODIFY COLUMN v1 VECTOR(4) COMMENT "";
Parâmetros de índice vetorial
|
Parâmetro |
Descrição |
|
|
Controla se o IMCI cria índices vetoriais durante a inicialização. ON (padrão): o nó somente leitura IMCI constrói um índice vetorial com base no |
|
|
Controla quando a tarefa em segundo plano grava dados incrementais no índice vetorial. Quando o número de novas linhas desde o último snapshot excede esse limiar, a tarefa em segundo plano libera os dados. Valores válidos: 1–4.294.967.295. Padrão: 1.000. |
Consultas vetoriais
Cálculo de distância
Use a função DISTANCE para calcular a similaridade entre dois vetores.
DISTANCE(vector1, vector2, '<metric>')
|
Métrica |
Descrição |
|
|
Distância cosseno. Mede a similaridade direcional entre dois vetores. Um valor menor indica maior similaridade. |
|
|
Distância euclidiana. Mede a distância em linha reta entre dois pontos. Um valor menor indica maior similaridade. |
|
|
Produto escalar. Multiplica os componentes correspondentes e soma os resultados. Um valor menor indica maior similaridade. |
SELECT DISTANCE(v1, STRING_TO_VECTOR('[1.2,2.3,3.4,4.5]'), 'COSINE') FROM t1;
Busca ANN
A busca ANN utiliza um índice vetorial para recuperar vizinhos mais próximos aproximados de forma eficiente. Todas as condições a seguir devem ser atendidas para que o otimizador use o índice vetorial:
A consulta inclui as cláusulas
ORDER BYeLIMIT.A primeira expressão em
ORDER BYéDISTANCE(...).A direção de ordenação é
ASC.A coluna vetorial em
DISTANCE(...)possui um índice vetorial ativo.A
metricemDISTANCE(...)corresponde àmetricusada para construir o índice.Se a consulta incluir um
JOIN, o plano de execução deve usar uma Right Deep Join Tree, e o campoDISTANCE(...)deve vir da tabela condutora.A consulta não pode conter
GROUP BY. Para agregar resultados, envolva a busca vetorial em uma subconsulta.
Ative a busca ANN:
Execute estes dois comandos no nível da sessão antes de executar consultas ANN.
-- Allow the optimizer to use vector indexes
SET imci_enable_vector_search = ON;
-- Force queries to use the column store execution path
SET cost_threshold_for_imci = 0;
SET cost_threshold_for_imci = 0 força todas as consultas na sessão a usar o índice columnstore. Isso pode degradar consultas pontuais que executam eficientemente no row store. Use esta configuração apenas em sessões dedicadas à recuperação vetorial — não a defina globalmente.
Execute uma consulta ANN:
-- Find the top 5 most similar records
SELECT id, v1
FROM t1
WHERE category_id = 123
ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[...]'), 'COSINE') ASC
LIMIT 5;
Usando GROUP BY com busca vetorial:
GROUP BY não pode aparecer na mesma consulta que ORDER BY DISTANCE(...). Execute a busca vetorial em uma subconsulta primeiro e depois agregue.
-- Incorrect: GROUP BY conflicts with ORDER BY DISTANCE()
-- SELECT category_id, COUNT(*) FROM t1
-- GROUP BY category_id
-- ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[...]'), 'COSINE') ASC
-- LIMIT 5;
-- Correct: perform ANN search in a subquery, then aggregate
SELECT category_id, COUNT(*)
FROM (
SELECT id, category_id
FROM t1
ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[...]'), 'COSINE') ASC
LIMIT 100
) AS nearest_neighbors
GROUP BY category_id;
Parâmetros de busca ANN:
|
Parâmetro |
Descrição |
|
|
Controla se os índices vetoriais aceleram a busca ANN. ON (padrão): ativado. OFF: desativado. |
|
|
Fator de expansão de recall para |
Busca KNN (exata)
A busca KNN percorre todos os dados para calcular distâncias, garantindo 100% de recall. Ela não requer um índice vetorial e é adequada para pequenos conjuntos de dados.
-- Find the 10 most similar records
SELECT id, VECTOR_TO_STRING(v1)
FROM t1
ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[1.2,2.3,3.4,4.5]'), 'COSINE')
LIMIT 10;
Consultas vetoriais com predicados
Adicione condições WHERE para filtrar resultados juntamente com a similaridade vetorial.
SELECT * FROM t1
WHERE id < 10
ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[1.2, 2.3, 3.4, 4.5]'), 'COSINE')
LIMIT 2;
O otimizador seleciona uma das três estratégias de execução com base na seletividade estimada do filtro:
|
Estratégia |
Quando se aplica |
|
Prefilter |
Linhas correspondentes estimadas < |
|
Postfilter |
Taxa de correspondência estimada >= |
|
Inline filter |
Nem prefilter nem postfilter se aplicam. Constrói um bitmap a partir das linhas que correspondem ao predicado e depois usa o bitmap durante a travessia do índice vetorial para garantir que os resultados satisfaçam a condição. |
Execução adaptativa: Se a estimativa de contagem de linhas do otimizador for imprecisa, o sistema pode trocar de estratégias em tempo de execução. Por exemplo, ao usar a estratégia inline filter, se o número real de linhas correspondentes for menor que imci_vector_search_prefilter_rows, o sistema muda dinamicamente para prefilter.
Otimização de partição: Para predicados baseados em IDs de locatário ou tags, use o particionamento LIST DEFAULT HASH. O otimizador usa poda de partição para selecionar a melhor estratégia por partição — postfilter para partições grandes, prefilter ou inline filter para as menores.
Parâmetros de predicado:
|
Parâmetro |
Descrição |
|
|
Se a seletividade estimada estiver neste valor ou acima dele, o sistema prioriza a recuperação por índice vetorial. Valores válidos: 0–100. Padrão: 20 (%). |
|
|
Controla se a estratégia inline filter está disponível. OFF (padrão): desativado. ON: ativado. |
|
|
Se o número estimado de linhas correspondentes estiver abaixo deste valor, o sistema usa a estratégia prefilter. Valores válidos: 0–UINT64_MAX. Padrão: 10.000. |
Monitorar status do índice vetorial
A construção do índice vetorial e o avanço do snapshot columnstore são executados como tarefas separadas em segundo plano. Com gravações contínuas, o snapshot do índice vetorial pode ficar atrasado em relação aos dados do columnstore. Verifique as seguintes visualizações do sistema para confirmar se o índice está pronto antes de executar buscas vetoriais.
Deslocamento do snapshot do índice
Consulte INFORMATION_SCHEMA.IMCI_INDEX_STATS para ver quantos vetores o índice columnstore carregou em seu snapshot.
SELECT schema_name, table_name, vector_rows
FROM information_schema.imci_index_stats;
Um valor VECTOR_ROWS igual a 0 significa que nenhum snapshot de índice vetorial está disponível — ou a tabela não tem índice vetorial, ou um índice recém-criado ainda não gerou um snapshot válido.
Compare VECTOR_ROWS com ROW_ID em INFORMATION_SCHEMA.IMCI_INDEXES para estimar a latência de construção. O índice vetorial ainda funciona com alguma latência — quaisquer vetores ainda não gravados no índice são tratados automaticamente durante uma busca.
Status físico do índice vetorial
Consulte INFORMATION_SCHEMA.IMCI_VECTOR_INDEX_STATS para inspecionar o estado físico de cada índice vetorial.
SELECT schema_name, table_name, column_name, vectors, memory_usage, storage_usage
FROM information_schema.imci_vector_index_stats;
|
Coluna |
Descrição |
|
|
Nome do banco de dados |
|
|
Nome da tabela |
|
|
Nome da coluna vetorial |
|
|
Número de vetores no índice. Exclui valores NULL e linhas excluídas durante a construção. |
|
|
Memória usada pelo índice |
|
|
Tamanho do arquivo de índice persistido em disco |
|
|
Tipo de índice. Atualmente, apenas |
|
|
Parâmetros de construção do índice em formato JSON |
A busca ANN fica indisponível para qualquer coluna não retornada por esta visualização. Um valorVECTORSigual a 0 após uma reinicialização do cluster não significa que o índice foi perdido. O índice é persistido em disco. A primeira consulta após uma reinicialização aciona o carregamento dos dados na memória. Para informações precisas sobre snapshots, useVECTOR_ROWSemINFORMATION_SCHEMA.IMCI_INDEX_STATS.
Exemplo: verificar um índice de ponta a ponta
Defina
imci_vector_index_dump_rows_thresholdcomo1no console do PolarDB para permitir que o índice seja construído com um pequeno número de linhas. Para obter instruções, consulte Especificar parâmetros de cluster e nó.-
Crie uma tabela de teste e insira dados:
CREATE TABLE t1 ( id INT AUTO_INCREMENT PRIMARY KEY, v1 VECTOR(4) COMMENT "imci_vector_index=HNSW(metric=COSINE,max_degree=16,ef_construction=300)" ) COMMENT "COLUMNAR=1"; INSERT INTO t1 VALUES (1, STRING_TO_VECTOR('[1.1,1.2,1.3,1.4]')), (2, STRING_TO_VECTOR('[2,2.2,2.4,2.6]')); -
Verifique o status do snapshot do índice:
SELECT schema_name, table_name, row_id FROM information_schema.imci_indexes; -- Expected: row_id = 2 SELECT schema_name, table_name, vector_rows FROM information_schema.imci_index_stats; -- Expected: vector_rows = 2 SELECT schema_name, table_name, column_name, vectors FROM information_schema.imci_vector_index_stats; -- Expected: vectors = 2 -
Insira uma terceira linha:
INSERT INTO t1 VALUES (3, STRING_TO_VECTOR('[8.8,8.88,8.888,8.8888]'));Consulte
IMCI_VECTOR_INDEX_STATSnovamente —VECTORSdeve agora ser 3, confirmando que a tarefa em segundo plano liberou a nova linha para o índice. -
Reinicie o nó somente leitura IMCI. Após a reinicialização,
VECTORSemIMCI_VECTOR_INDEX_STATSretorna 0, enquantoVECTOR_ROWSemIMCI_INDEX_STATSainda mostra 3. Isso é esperado — os dados do índice estão em disco, mas ainda não foram carregados na memória.ImportanteReiniciar o nó somente leitura IMCI causa uma breve interrupção do serviço.
-
Execute uma consulta aproximada para acionar o carregamento do índice:
SET cost_threshold_for_imci = 0; EXPLAIN SELECT * FROM t1 ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[1.2, 2.3, 3.4, 4.5]'), 'COSINE') LIMIT 1; -- The execution plan should contain Vector Search SELECT id, VECTOR_TO_STRING(v1) FROM t1 ORDER BY DISTANCE(v1, STRING_TO_VECTOR('[1.2, 2.3, 3.4, 4.5]'), 'COSINE') LIMIT 1;Consulte
IMCI_VECTOR_INDEX_STATSnovamente —VECTORSretorna a 3, confirmando que o índice está carregado e totalmente operacional.