Nesta página, descrevemos como usar embeddings armazenadas para gerar índices e consultar embeddings usando o índice ScaNN
com o AlloyDB para PostgreSQL.
Para mais informações sobre como armazenar embeddings, consulte
Armazenar embeddings de vetor.
O AlloyDB alloydb_scann
, uma extensão do PostgreSQL desenvolvida pelo Google que implementa um índice de vizinho mais próximo altamente eficiente com tecnologia do algoritmo ScaNN.
O índice ScaNN
é um índice de quantização baseado em árvore para pesquisa aproximada de vizinho mais próximo. Ele oferece um tempo de criação de índice menor e um consumo de memória menor em comparação com HNSW
. Além disso, ele oferece QPS mais rápido em comparação com HNSW
com base na carga de trabalho.
Antes de começar
Antes de começar a criar índices, conclua os seguintes pré-requisitos.
Os vetores de embedding são adicionados a uma tabela no banco de dados do AlloyDB.
A extensão
vector
, que é baseada empgvector
, estendida pelo Google para o AlloyDB, e a extensãoalloydb_scann
estão instaladas:CREATE EXTENSION IF NOT EXISTS alloydb_scann CASCADE;
Se você quiser criar índices ScaNN ajustados automaticamente, verifique se a flag
scann.enable_preview_features
está ativada. Se você não quiser ativar os recursos de prévia ou para instâncias de produção, crie um índice do ScaNN com parâmetros específicos.
Criar um índice ScaNN ajustado automaticamente
Com o recurso de indexação automática, é possível simplificar a criação de índices para gerar automaticamente índices otimizados para a performance de pesquisa ou tempos de criação de índice e performance de pesquisa equilibrados.
Ao usar o modo AUTO
, basta especificar o nome da tabela e a coluna de embedding, além da função de distância que você quer usar. É possível otimizar o índice para a performance de pesquisa ou equilibrar os tempos de criação do índice e a performance de pesquisa.
Há também a opção de usar o modo MANUAL
para criar índices com controle granular sobre outros parâmetros de ajuste.
Criar um índice ScaNN no modo AUTO
Alguns pontos a serem observados antes de criar índices no modo AUTO
:
- O AlloyDB não pode criar um índice ScaNN para tabelas com dados insuficientes.
- Não é possível definir parâmetros de criação de índice, como
num_leaves
, ao criar índices no modoAUTO
. - A manutenção automática é ativada por padrão para todos os índices criados no modo
AUTO
.
Para criar um índice no modo AUTO
, execute o seguinte comando:
CREATE INDEX INDEX_NAME ON TABLE \
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) \
WITH (mode=AUTO', optimization='OPTIMIZATION');
Substitua:
INDEX_NAME
: o nome do índice que você quer criar, por exemplo,my-scann-index
. Os nomes de índice são compartilhados em todo o banco de dados. Verifique se cada nome de índice é exclusivo para cada tabela no banco de dados.TABLE
: a tabela em que o índice será adicionado.EMBEDDING_COLUMN
: a coluna que armazena dados devector
.DISTANCE_FUNCTION
: a função de distância a ser usada com esse índice. Escolha uma destas opções:Distância de L2:
l2
Produto escalar:
dot_product
Distância do cosseno:
cosine
OPTIMIZATION
: defina como uma das seguintes opções:SEARCH_OPTIMIZED
: para otimizar a recall e a latência da pesquisa vetorial a um custo de maior tempo de criação do índice.BALANCED
: para criar um índice que equilibre o tempo de criação e o desempenho da pesquisa.
Criar um índice ScaNN
no modo MANUAL
Se você ativou a flag scann.enable_preview_features
e quer ter um controle granular sobre os parâmetros de ajuste, crie o índice no modo MANUAL
.
Para criar um índice ScaNN
no modo MANUAL
, execute o seguinte comando:
CREATE INDEX INDEX_NAME ON TABLE \
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) \
WITH (mode='MANUAL, num_leaves=NUM_LEAVES_VALUE, [quantizer =QUANTIZER, max_num_levels=MAX_NUM_LEVELS]);
Substitua:
INDEX_NAME
: o nome do índice que você quer criar, por exemplo,my-scann-index
. Os nomes de índice são compartilhados em todo o banco de dados. Verifique se cada nome de índice é exclusivo para cada tabela no banco de dados.TABLE
: a tabela em que o índice será adicionado.EMBEDDING_COLUMN
: a coluna que armazena dados devector
.DISTANCE_FUNCTION
: a função de distância a ser usada com esse índice. Escolha uma destas opções:Distância de L2:
l2
Produto escalar:
dot_product
Distância do cosseno:
cosine
NUM_LEAVES_VALUE
: o número de partições a serem aplicadas a esse índice. Definido como qualquer valor entre 1 e 1.048.576.QUANTIZER
: o tipo de quantizador que você quer usar para a árvore K-means. O valor padrão é SQ8, que oferece melhor desempenho de consulta com perda mínima de recall (normalmente menos de 1 a 2%). Você também pode definir comoFLAT
para uma recall de 99% ou mais.MAX_NUM_LEVELS
: o número máximo de níveis da árvore de agrupamento K-means. Defina como1
(padrão) para quantização de árvore de dois níveis e como2
para quantização de árvore de três níveis.
Você pode adicionar outros parâmetros de criação de índice ou de tempo de execução da consulta para ajustar o índice. Para mais informações, consulte Ajustar um índice ScaNN
.
Mudar os modos dos índices atuais
Se você criou um índice ScaNN usando o modo AUTO
e quer ajustar o índice manualmente, mude o modo para MANUAL
.
Para mudar para o modo MANUAL
, siga estas etapas:
Atualize o índice para definir o modo como
MANUAL
:ALTER INDEX INDEX_NAME SET (mode = 'MANUAL', num_leaves = NUM_LEAVES_VALUE);
Substitua:
INDEX_NAME
: o nome do índice que você quer criar, por exemplo,my-scann-index
. Os nomes de índice são compartilhados em todo o banco de dados. Verifique se cada nome de índice é exclusivo para cada tabela no banco de dados.NUM_LEAVES_VALUE
: o número de partições a serem aplicadas a esse índice. Definido como qualquer valor entre 1 e 1.048.576.
Você pode adicionar outros parâmetros de criação de índice ou de tempo de execução da consulta para ajustar o índice. Para mais informações, consulte Ajustar um índice
ScaNN
.Recrie o índice para aplicar os parâmetros:
REINDEX INDEX CONCURRENTLY INDEX_NAME;
Para mudar para o modo AUTO
, siga estas etapas:
Atualize o índice para definir o modo como
AUTO
:ALTER INDEX INDEX_NAME SET (mode = 'AUTO');
Recrie o índice para aplicar os parâmetros:
REINDEX INDEX CONCURRENTLY INDEX_NAME;
Criar um índice ScaNN
com parâmetros específicos
Se o aplicativo tiver requisitos específicos para recall e tempos de
criação de índice, crie o índice manualmente. É possível criar um índice de árvore de dois ou três níveis com base na sua carga de trabalho. Para mais informações sobre o ajuste de parâmetros, consulte Ajustar um índice ScaNN
.
Índice de árvore de dois níveis
Para aplicar um índice de árvore de dois níveis usando o algoritmo ScaNN a uma coluna que contém embeddings de vetores armazenados, execute a seguinte consulta DDL:
CREATE INDEX INDEX_NAME ON TABLE
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
WITH (num_leaves=NUM_LEAVES_VALUE);
Substitua:
INDEX_NAME
: o nome do índice que você quer criar, por exemplo,my-scann-index
. Os nomes de índice são compartilhados em todo o banco de dados. Verifique se cada nome de índice é exclusivo para cada tabela no banco de dados.TABLE
: a tabela em que o índice será adicionado.EMBEDDING_COLUMN
: uma coluna que armazena dados devector
.DISTANCE_FUNCTION
: a função de distância a ser usada com esse índice. Escolha uma destas opções:Distância de L2:
l2
Produto escalar:
dot_product
Distância do cosseno:
cosine
NUM_LEAVES_VALUE
: o número de partições a serem aplicadas a esse índice. Definido como qualquer valor entre 1 e 1.048.576. Para mais informações sobre como decidir esse valor, consulte Ajustar um índiceScaNN
.
Índice de árvore de três níveis
Para criar um índice de árvore de três níveis usando o algoritmo ScaNN em uma coluna que contém embeddings de vetores armazenados, execute a seguinte consulta DDL:
CREATE INDEX INDEX_NAME ON TABLE
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = 2);
Depois de criar o índice, siga as instruções em Fazer uma consulta de vizinho mais próximo com um texto fornecido para executar consultas de pesquisa de vizinho mais próximo que usam o índice.
Os parâmetros de índice precisam ser definidos para encontrar o equilíbrio certo entre QPS e recall. Para mais informações sobre como ajustar o índice ScaNN
, consulte Ajustar um índice ScaNN
.
Para criar esse índice em uma coluna incorporada que usa o tipo de dados real[]
em vez de vector
, converta a coluna no tipo de dados vector
:
CREATE INDEX INDEX_NAME ON TABLE
USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)
WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);
Substitua DIMENSIONS
pela largura dimensional da coluna de embedding. Para mais informações sobre como encontrar as dimensões, consulte a função vector_dims
em Funções de vetor.
Para ter uma experiência de pesquisa consistente, ative a manutenção automática ao criar um índice ScaNN. Para mais informações, consulte Manter índices vetoriais. Esse recurso está disponível em Pré-lançamento.
Para conferir o progresso da indexação, use a visualização pg_stat_progress_create_index
:
SELECT * FROM pg_stat_progress_create_index;
A coluna phase
mostra o estado atual da criação do índice. Depois que a fase de criação do índice é concluída, a linha do índice não fica visível.
Para ajustar seu índice para um recall médio e um equilíbrio de QPS, consulte Ajustar um índice ScaNN
.
Criar índices em paralelo
Para criar seu índice mais rápido, o AlloyDB pode gerar automaticamente vários workers paralelos, dependendo do conjunto de dados e do tipo de índice escolhido.
A criação de índice paralela geralmente é acionada se você estiver criando um índice ScaNN de três níveis ou se o conjunto de dados exceder 100 milhões de linhas.
Embora o AlloyDB otimize automaticamente o número de workers paralelos, é possível ajustar esses workers usando os parâmetros de planejamento de consultas do PostgreSQL max_parallel_maintenance_workers
, max_parallel_workers
e min_parallel_table_scan_size
.
Executar uma consulta
Depois de armazenar e indexar os embeddings no banco de dados, você pode começar a consultar os dados. Não é possível executar
consultas de pesquisa em massa usando a extensão alloydb_scann
.
Para encontrar os vizinhos semânticos mais próximos de um vetor de embedding, execute a consulta de exemplo a seguir, em que você define a mesma função de distância usada durante a criação do índice.
SELECT * FROM TABLE
ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY ['EMBEDDING']
LIMIT ROW_COUNT
Substitua o seguinte:
TABLE
: a tabela que contém o embedding com o qual você vai comparar o texto.INDEX_NAME
: o nome do índice que você quer usar. Por exemplo,my-scann-index
.EMBEDDING_COLUMN
: a coluna que contém os embeddings armazenados.DISTANCE_FUNCTION_QUERY
: a função de distância a ser usada com essa consulta. Escolha uma das seguintes opções com base na função de distância usada ao criar o índice:Distância de L2:
<->
Produto interno:
<#>
Distância do cosseno:
<=>
EMBEDDING
: o vetor de embedding para encontrar os vizinhos semânticos armazenados mais próximos.ROW_COUNT
: o número de linhas que serão retornadas.Especifique
1
se você quiser apenas a melhor correspondência.
Você também pode usar a função embedding()
para traduzir o
texto em um vetor. Como embedding()
retorna uma matriz real
, é necessário transmitir explicitamente a
chamada embedding()
para vector
antes de aplicá-la a um dos
operadores de vizinho mais próximo (por exemplo, <->
para distância L2). Em seguida, esses operadores podem usar o índice ScaNN para encontrar as linhas do banco de dados com os embeddings mais semanticamente semelhantes.
A seguir
- Fazer pesquisas de similaridade vetorial
- Ajustar o desempenho da consulta de vetores
- Métricas de índice vetorial
- Aprenda a criar um assistente de compras inteligente com o AlloyDB, o pgvector e o gerenciamento de endpoints de modelo.