Este documento mostra como ajustar os seus índices para alcançar um desempenho de consulta mais rápido e uma melhor capacidade de memorização.
Ajuste um índice ScaNN
O índice ScaNN usa a indexação baseada na quantização de árvores. Nas técnicas de quantização de árvores, os índices aprendem uma árvore de pesquisa juntamente com uma função de quantização (ou hash). Quando executa uma consulta, a árvore de pesquisa é usada para reduzir o espaço de pesquisa, enquanto a quantização é usada para comprimir o tamanho do índice. Esta remoção acelera a classificação da semelhança (ou seja, a distância) entre o vetor de consulta e os vetores da base de dados.
Para alcançar uma taxa de consultas por segundo (QPS) elevada e uma elevada capacidade de memorização com as suas consultas de vizinho mais próximo, tem de particionar a árvore do seu índice ScaNN
da forma mais adequada aos seus dados e consultas.
Antes de criar um índice ScaNN
, conclua o seguinte:
- Certifique-se de que já criou uma tabela com os seus dados.
- Certifique-se de que o valor que define para o indicador
maintenance_work_mem
eshared_buffers
é inferior à memória total da máquina para evitar problemas ao gerar o índice.
Parâmetros de aperfeiçoamento
Os seguintes parâmetros de índice e flags da base de dados são usados em conjunto para encontrar o equilíbrio certo entre a capacidade de memorização e as QPS. Todos os parâmetros aplicam-se a ambos os tipos de índice ScaNN
.
Parâmetro de aperfeiçoamento | Descrição | Tipo de parâmetro |
---|---|---|
num_leaves |
O número de partições a aplicar a este índice. O número de partições que aplica quando cria um índice afeta o desempenho do índice. Ao aumentar as partições para um número definido de vetores, cria um índice mais detalhado, o que melhora a capacidade de memorização e o desempenho das consultas. No entanto, isto tem o custo de tempos de criação de índices mais longos. Uma vez que as árvores de três níveis são criadas mais rapidamente do que as árvores de dois níveis, pode aumentar o num_leaves_value quando cria um índice de árvore de três níveis para alcançar um melhor desempenho.
|
Criação de índice |
quantizer |
O tipo de quantizador que quer usar para a árvore K-means. O valor predefinido é SQ8 para um melhor desempenho das consultas.Defina-o como FLAT para uma melhor capacidade de memorização. |
Criação de índice |
enable_pca |
Ativa a análise de componentes principais (PCA), que é uma técnica de redução de dimensões usada para reduzir automaticamente
o tamanho da incorporação sempre que possível. Esta opção está ativada por predefinição. Defina como false se observar uma deterioração na capacidade de memorização. |
Criação de índice |
scann.num_leaves_to_search |
O indicador da base de dados controla a compensação entre a capacidade de memorização e as QPS. O valor predefinido é 1% do valor definido em num_leaves . Quanto mais alto for o valor definido, melhor é a capacidade de memorização, mas resulta num QPS mais baixo e vice-versa. |
Tempo de execução da consulta |
scann.max_top_neighbors_buffer_size |
A flag da base de dados especifica o tamanho da cache usada para melhorar o desempenho das consultas filtradas através da classificação dos vizinhos candidatos analisados na memória em vez do disco. O valor predefinido é 20000 . Quanto mais elevado for o valor definido, melhor é o QPS em consultas filtradas, mas resulta numa maior utilização de memória e vice-versa. |
Tempo de execução da consulta |
scann.pre_reordering_num_neighbors |
Quando definida, a flag da base de dados especifica o número de vizinhos candidatos a considerar durante as fases de reordenação depois de a pesquisa inicial identificar um conjunto de candidatos. Defina este valor como superior ao número de vizinhos que quer que a consulta devolva. Os conjuntos de valores mais elevados resultam numa melhor recordação, mas esta abordagem resulta num QPS mais baixo. |
Tempo de execução da consulta |
max_num_levels |
O número máximo de níveis da árvore de agrupamento K-means.
|
Criação de índice |
Ajuste um índice ScaNN
Considere os seguintes exemplos para índices de ScaNN
de dois e três níveis que mostram como os parâmetros de otimização são definidos:
Índice de dois níveis
SET LOCAL scann.num_leaves_to_search = 1;
SET LOCAL scann.pre_reordering_num_neighbors=50;
CREATE INDEX my-scann-index ON my-table
USING scann (vector_column cosine)
WITH (num_leaves = [power(1000000, 1/2)]);
Índice de três níveis
SET LOCAL scann.num_leaves_to_search = 10;
SET LOCAL scann.pre_reordering_num_neighbors=50;
CREATE INDEX my-scann-index ON my-table
USING scann (vector_column cosine)
WITH (num_leaves = [power(1000000, 2/3)], max_num_levels = 2);
Qualquer operação de inserção ou atualização numa tabela em que já tenha sido gerado um índice ScaNN
afeta a forma como a árvore de aprendizagem otimiza o índice. Se a sua tabela for propensa a atualizações ou inserções frequentes, recomendamos que reindexe periodicamente o índice ScaNN
existente para melhorar a precisão da obtenção.
Pode monitorizar as métricas de índice para determinar a quantidade de mutações criadas desde a criação do índice e, em seguida, reindexar em conformidade. Para mais informações sobre as métricas, consulte as métricas do índice de vetores.
Práticas recomendadas para a otimização
Com base no tipo de índice ScaNN
que planeia usar, as recomendações para otimizar o índice variam. Esta secção fornece recomendações sobre como ajustar os parâmetros de índice para um equilíbrio ideal entre a capacidade de memorização e as QPS.
Índice de árvore de dois níveis
Para aplicar recomendações que ajudam a encontrar os valores ideais de num_leaves
e num_leaves_to_search
para o seu conjunto de dados,
siga estes passos:
- Crie o índice
ScaNN
comnum_leaves
definido como a raiz quadrada da contagem de linhas da tabela indexada. - Execute as suas consultas de teste, aumentando o valor de
scann.num_of_leaves_to_search
, até atingir o intervalo de recall alvo, por exemplo, 95%. Para mais informações sobre a análise das suas consultas, consulte o artigo Analise as suas consultas. - Tome nota da proporção entre
scann.num_leaves_to_search
enum_leaves
que vai ser usada nos passos seguintes. Esta proporção fornece uma aproximação em torno do conjunto de dados que vai ajudar a alcançar a sua capacidade de memorização alvo.
Se estiver a trabalhar com vetores de dimensões elevadas (500 dimensões ou mais) e quiser melhorar a capacidade de memorização, experimente ajustar o valor descann.pre_reordering_num_neighbors
. Como ponto de partida, defina o valor como100 * sqrt(K)
, em queK
é o limite que definiu na consulta. - Se o seu QPS for demasiado baixo depois de as suas consultas atingirem uma taxa de obtenção alvo, siga estes passos:
- Recrie o índice, aumentando o valor de
num_leaves
escann.num_leaves_to_search
de acordo com as seguintes orientações:- Defina
num_leaves
para um fator maior da raiz quadrada da contagem de linhas. Por exemplo, se o índice tivernum_leaves
definido como a raiz quadrada da contagem de linhas, experimente defini-lo como o dobro da raiz quadrada. Se o valor já for o dobro, experimente defini-lo como o triplo da raiz quadrada. - Aumente
scann.num_leaves_to_search
conforme necessário para manter a respetiva proporção comnum_leaves
, que indicou no passo 3. - Defina
num_leaves
para um valor inferior ou igual à contagem de linhas dividida por 100.
- Defina
- Execute novamente as consultas de teste.
Enquanto executa as consultas de teste, experimente reduzir
scann.num_leaves_to_search
e encontrar um valor que aumente as QPS, mantendo a taxa de recordação elevada. Experimente valores diferentes descann.num_leaves_to_search
sem reconstruir o índice.
- Recrie o índice, aumentando o valor de
- Repita o passo 4 até o QPS e o intervalo de recolha terem atingido valores aceitáveis.
Índice de árvore de três níveis
Além das recomendações para o índice de árvore de ScaNN
níveis, use as seguintes orientações e os passos para otimizar o índice:
- Aumentar o valor de
max_num_levels
de1
para uma árvore de dois níveis para2
para uma árvore de três níveis reduz significativamente o tempo de criação de um índice, mas à custa da precisão da capacidade de recordar. Definamax_num_levels
com a seguinte recomendação:- Defina o valor como
2
se o número de linhas vetoriais exceder 100 milhões de linhas. - Defina o valor como
1
se o número de linhas de vetores for inferior a 10 milhões de linhas. - Defina como
1
ou2
se o número de linhas de vetores estiver entre 10 milhões e 100 milhões de linhas, com base no equilíbrio entre o tempo de criação do índice e a precisão de recolha de que precisa.
- Defina o valor como
Para aplicar recomendações para encontrar o valor ideal dos parâmetros de índice num_leaves
e max_num_levels
, siga estes passos:
Crie o índice
ScaNN
com as seguintes combinações denum_leaves
emax_num_levels
com base no seu conjunto de dados:- vector rows greater than 100 million rows: defina
max_num_levels
como2
enum_leaves
comopower(rows, ⅔)
. - linhas de vetores com menos de 100 milhões de linhas: defina
max_num_levels
como1
enum_leaves
comosqrt(rows)
. - Linhas de vetores entre 10 milhões e 100 milhões de linhas: comece por definir
max_num_levels
como1
enum_leaves
comosqrt(rows)
.
- vector rows greater than 100 million rows: defina
Execute as suas consultas de teste. Para mais informações sobre a análise de consultas, consulte o artigo Analise as suas consultas.
Se o tempo de criação do índice for satisfatório, mantenha o valor
max_num_levels
e experimente o valornum_leaves
para uma precisão de memorização ideal.Se não estiver satisfeito com o tempo de criação do índice, faça o seguinte:
Se o valor de
max_num_levels
for1
, elimine o índice. Reconstrua o índice com o valormax_num_levels
definido como2
.Execute as consultas e ajuste o valor de
num_leaves
para uma precisão de memorização ideal.Se o valor
max_num_levels
for2
, elimine o índice. Reconstrua o índice com o mesmo valormax_num_levels
e ajuste o valornum_leaves
para uma precisão de recolha ideal.
Ajuste um índice IVF
Ajustar os valores que define para os parâmetros lists
, ivf.probes
e quantizer
pode ajudar a otimizar o desempenho da sua aplicação:
Parâmetro de aperfeiçoamento | Descrição | Tipo de parâmetro |
---|---|---|
lists |
O número de listas criadas durante a criação do índice. O ponto de partida para definir este valor é (rows)/1000 para até um milhão de linhas e sqrt(rows) para mais de um milhão de linhas. |
Criação de índice |
quantizer |
O tipo de quantizador que quer usar para a árvore K-means. O valor predefinido é SQ8 para um melhor desempenho das consultas. Defina-o como FLAT para uma melhor memorização. |
Criação de índice |
ivf.probes |
O número de listas mais próximas a explorar durante a pesquisa. O ponto de partida para este valor é sqrt(lists) . |
Tempo de execução da consulta |
Considere o exemplo seguinte que mostra um índice IVF
com os parâmetros de otimização definidos:
SET LOCAL ivf.probes = 10;
CREATE INDEX my-ivf-index ON my-table
USING ivf (vector_column cosine)
WITH (lists = 100, quantizer = 'SQ8');
Ajuste um índice IVFFlat
Ajustar os valores que define para os parâmetros lists
e ivfflat.probes
pode ajudar a otimizar o desempenho da aplicação:
Parâmetro de aperfeiçoamento | Descrição | Tipo de parâmetro |
---|---|---|
lists |
O número de listas criadas durante a criação do índice. O ponto de partida para definir este valor é (rows)/1000 para até um milhão de linhas e sqrt(rows) para mais de um milhão de linhas. |
Criação de índice |
ivfflat.probes |
O número de listas mais próximas a explorar durante a pesquisa. O ponto de partida para este valor é sqrt(lists) . |
Tempo de execução da consulta |
Antes de criar um índice IVFFlat
, certifique-se de que a flag max_parallel_maintenance_workers
da sua base de dados está definida para um valor suficiente para acelerar a criação do índice em tabelas grandes.
Considere o exemplo seguinte que mostra um índice IVFFlat
com os parâmetros de otimização definidos:
SET LOCAL ivfflat.probes = 10;
CREATE INDEX my-ivfflat-index ON my-table
USING ivfflat (vector_column cosine)
WITH (lists = 100);
Ajuste um índice HNSW
Ajustar os valores que define para os parâmetros m
, ef_construction
e hnsw.ef_search
pode ajudar a otimizar o desempenho da aplicação.
Parâmetro de aperfeiçoamento | Descrição | Tipo de parâmetro |
---|---|---|
m |
O número máximo de associações por nó no gráfico. Pode começar com o valor predefinido 16 (predefinição) e experimentar valores mais elevados com base no tamanho do seu conjunto de dados. |
Criação de índice |
ef_construction |
O tamanho da lista de candidatos dinâmicos mantida durante a construção do gráfico, que atualiza constantemente os melhores candidatos atuais para os vizinhos mais próximos de um nó. Defina este valor para qualquer valor superior ao dobro do valor m , por exemplo, 64 (predefinição). |
Criação de índice |
ef_search |
O tamanho da lista de candidatos dinâmicos usada durante a pesquisa. Pode começar a definir este valor como m ou ef_construction e, em seguida, alterá-lo enquanto observa a recolha. O valor predefinido é 40 . |
Tempo de execução da consulta |
Considere o exemplo seguinte que mostra um índice hnsw
com os parâmetros de otimização definidos:
SET LOCAL hnsw.ef_search = 40;
CREATE INDEX my-hnsw-index ON my-table
USING hnsw (vector_column cosine)
WITH (m = 16, ef_construction = 200);
Analise as suas consultas
Use o comando EXPLAIN ANALYZE
para analisar as estatísticas de consultas, conforme mostrado no seguinte exemplo de consulta SQL.
EXPLAIN ANALYZE SELECT result-column FROM my-table
ORDER BY EMBEDDING_COLUMN ::vector
USING INDEX my-scann-index
<-> embedding('textembedding-gecko@003', 'What is a database?')
LIMIT 1;
A resposta de exemplo QUERY PLAN
inclui informações como o tempo necessário, o número de linhas analisadas ou devolvidas e os recursos usados.
Limit (cost=0.42..15.27 rows=1 width=32) (actual time=0.106..0.132 rows=1 loops=1)
-> Index Scan using my-scann-index on my-table (cost=0.42..858027.93 rows=100000 width=32) (actual time=0.105..0.129 rows=1 loops=1)
Order By: (embedding_column <-> embedding('textgecko@003', 'What is a database?')::vector(768))
Limit value: 1
Planning Time: 0.354 ms
Execution Time: 0.141 ms
Veja métricas do índice vetorial
Pode usar as métricas do índice vetorial para rever o desempenho do índice vetorial, identificar áreas de melhoria e ajustar o índice com base nas métricas, se necessário.
Para ver todas as métricas do índice vetorial, execute a seguinte consulta SQL, que usa a vista pg_stat_ann_indexes
:
SELECT * FROM pg_stat_ann_indexes;
Para mais informações sobre a lista completa de métricas, consulte o artigo Métricas do índice vetorial.