Esta página descreve como encontrar vizinhos mais próximos aproximados (ANN, na sigla em inglês), criar índices de vetor e consultar embeddings de vetor usando as seguintes funções de distância ANN no Spanner:
APPROX_COSINE_DISTANCE
APPROX_EUCLIDEAN_DISTANCE
APPROX_DOT_PRODUCT
Quando um conjunto de dados é pequeno, é possível usar vizinhos mais próximos (KNN) para encontrar os vetores mais próximos. No entanto, à medida que o conjunto de dados cresce, a latência e o custo de uma pesquisa KNN também aumentam. É possível usar ANN para encontrar os vizinhos mais próximos k aproximados com latência e custo significativamente reduzidos.
Vizinhos k-mais próximos aproximados
Em uma pesquisa ANN, os vetores retornados não são os vizinhos mais próximos mais próximos. Ocasionalmente, alguns vetores que não estão entre os vizinhos mais próximos são retornados. Isso é conhecido como perda de recordação. A quantidade de perda de recall aceitável depende do caso de uso, mas, na maioria dos casos, perder um pouco de recall em troca de um melhor desempenho do banco de dados é uma compensação aceitável.
Para mais detalhes sobre as funções de distância aproximada do Spanner, consulte:
APPROX_COSINE_DISTANCE
no GoogleSQLAPPROX_EUCLIDEAN_DISTANCE
no GoogleSQLAPPROX_DOT_PRODUCT
no GoogleSQL
Índice vetorial
O Spanner acelera as pesquisas de vetor ANN usando um índice de vetor especializado. Esse índice usa o Vizinho mais próximo escalonável (ScaNN) da Google Research, um algoritmo de vizinho mais próximo altamente eficiente.
O índice de vetor usa uma estrutura baseada em árvore para particionar dados e facilitar pesquisas mais rápidas. O Spanner oferece configurações de árvore de dois e três níveis:
- Configuração de árvore de dois níveis: os nós de folha (
num_leaves
) contêm grupos de vetores intimamente relacionados e o centroide correspondente. O nível raiz é composto pelos centroides de todos os nós de folha. - Configuração de árvore de três níveis: semelhante em conceito a uma árvore de dois níveis, mas
com a introdução de uma camada de ramificação adicional (
num_branches
), a partir da qual os centroides de nós folhas são particionados para formar o nível raiz (num_leaves
).
Além disso, você precisa criar seu índice de vetores com uma métrica de distância específica.
Para escolher a métrica de distância mais adequada para seu caso de uso, defina
distance_type
como COSINE
, DOT_PRODUCT
ou EUCLIDEAN
.
Para mais informações, consulte as instruções VECTOR INDEX
.
Limitações
O índice de vetor de spanner tem as seguintes limitações:
ALTER VECTOR INDEX
não é compatível.
Criar índice vetorial
Para otimizar melhor o índice de vetores para uma boa recuperação e desempenho, recomendamos que você crie o índice de vetores depois que a maioria das linhas com incorporações for gravada no banco de dados. Talvez também seja necessário reconstruir periodicamente o índice de vetores depois de inserir novos dados. Para mais informações, consulte Recriar o índice vetorial.
Para criar um índice vetorial com uma árvore de dois níveis e 1.000 nós de folha em uma
tabela Documents
com uma coluna de embedding DocEmbedding
usando a distância
cosine:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(DocEmbedding)
OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);
Para criar um índice de vetores com uma árvore de três níveis e 1.000.000 nós de folhas:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(NullableDocEmbedding)
WHERE NullableDocEmbedding IS NOT NULL
OPTIONS (distance_type = 'COSINE', tree_depth = 3, num_branches=1000, num_leaves = 1000000);
Se a coluna de incorporação for anulável, ela precisará ser declarada com uma
cláusula WHERE column_name IS NOT NULL
:
CREATE VECTOR INDEX DocEmbeddingIndex
ON Documents(NullableDocEmbedding)
WHERE NullableDocEmbedding IS NOT NULL
OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);
Consultar embeddings de vetor
Para consultar um índice de vetor, use uma das três funções de distância aproximada:
APPROX_COSINE_DISTANCE
APPROX_EUCLIDEAN_DISTANCE
APPROX_DOT_PRODUCT
As restrições ao usar as funções de distância aproximada incluem:
- É necessário fornecer uma sugestão de consulta para usar o índice vetorial.
- É necessário usar uma expressão constante como um argumento da função de distância (por exemplo, um parâmetro ou um literal).
- A consulta ou subconsulta em que a função de distância aproximada é usada precisa
ter uma forma específica: a função de distância precisa ser a única chave
ORDER BY
, e um limite precisa ser especificado.
Para conferir uma lista detalhada de limitações, consulte a página de referência da função de distância aproximada.
Exemplo
Para pesquisar os 100 vetores mais próximos de [1.0, 2.0, 3.0]
:
SELECT DocId
FROM Documents@{FORCE_INDEX=DocEmbeddingIndex}
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
Se a coluna de inserção for anulável:
SELECT DocId
FROM Documents@{FORCE_INDEX=DocEmbeddingIndex}
WHERE NullableDocEmbedding IS NOT NULL
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
Práticas recomendadas
Siga estas práticas recomendadas para otimizar os índices de vetor e melhorar os resultados da consulta.
Ajustar as opções de pesquisa vetorial
O valor de pesquisa de vetor mais ideal depende do caso de uso, do conjunto de dados de vetor e dos vetores de consulta. Talvez seja necessário realizar um ajuste iterativo para encontrar os melhores valores para sua carga de trabalho específica.
Confira algumas diretrizes úteis para escolher os valores adequados:
tree_depth
(nível da árvore): se a tabela indexada tiver menos de 10 milhões de linhas, use umtree_depth
de2
. Caso contrário, umtree_depth
de3
oferece suporte a tabelas de até 10 bilhões de linhas.num_leaves
: use a raiz quadrada do número de linhas no conjunto de dados. Um valor maior pode aumentar o tempo de criação do índice vetorial. Evite definirnum_leaves
maior quetable_row_count/1000
, porque isso resulta em folhas muito pequenas e em uma performance ruim.num_leaves_to_search
: essa opção especifica quantos nós de folha do índice são pesquisados. Aumentarnum_leaves_to_search
melhora o recall, mas também aumenta a latência e o custo. Recomendamos usar um número que seja 1% do número total de folhas definidas na instruçãoCREATE VECTOR INDEX
como o valor denum_leaves_to_search
. Se você estiver usando uma cláusula de filtro, aumente esse valor para ampliar a pesquisa.
Se o recall aceitável for alcançado, mas o custo da consulta for muito alto,
resultando em QPS máxima baixa, tente aumentar num_leaves
seguindo estas
etapas:
- Defina
num_leaves
como um múltiplo k do valor original (por exemplo,2 * sqrt(table_row_count)
). - Defina
num_leaves_to_search
como o mesmo múltiplo k do valor original. - Experimente reduzir
num_leaves_to_search
para melhorar o custo e o QPS mantendo a recuperação.
Melhorar a lembrança
Há várias possibilidades de piora da revogação, incluindo as seguintes:
num_leaves_to_search
é muito pequeno: pode ser mais difícil encontrar os vizinhos mais próximos de alguns vetores de consulta. Portanto, aumentarnum_leaves_to_search
para pesquisar mais folhas pode ajudar a melhorar o recall. As consultas recentes podem ter mudado para conter mais desses vetores desafiadores.O índice de vetor precisa ser recriado: a estrutura de árvore do índice de vetor é otimizada para o conjunto de dados no momento da criação e fica estática depois disso. Portanto, se vetores significativamente diferentes forem adicionados após a criação do índice de vetor inicial, a estrutura de árvore poderá ser subótima, levando a uma recuperação mais fraca.
Recriar o índice vetorial
Para recriar o índice de vetores sem inatividade:
- Crie um novo índice vetorial na mesma coluna de inserção do índice vetorial
atual, atualizando os parâmetros (por exemplo,
OPTIONS
) conforme apropriado. - Depois que a criação do índice for concluída, mude a dica
FORCE_INDEX
para apontar para o novo índice e atualizar a consulta de pesquisa vetorial. Isso garante que a consulta use o novo índice de vetor. Talvez também seja necessário retornarnum_leaves_to_search
na nova consulta. - Descarte o índice vetorial desatualizado.
A seguir
Saiba mais sobre as funções
APPROXIMATE_COSINE_DISTANCE()
,APPROXIMATE_EUCLIDEAN_DISTANCE()
eAPPROXIMATE_DOT_PRODUCT()
do GoogleSQL.Saiba mais sobre as instruções
VECTOR INDEX
do GoogleSQL.