O tuning de HNSW e IVFFlat no pgvector deve começar pela comparação com uma busca exata, usando as mesmas perguntas e os mesmos filtros. Depois, ajuste a quantidade de candidatos examinados e acompanhe latência, recall e consumo de recursos. Criar um índice e observar uma consulta rápida não comprova que os documentos necessários continuam aparecendo.
Este guia trata de uma base PostgreSQL que já contém embeddings e consultas funcionais. Para a montagem inicial da aplicação, consulte a base de conhecimento com RAG e pgvector. Aqui, a decisão é operacional: descobrir se o problema está no plano de execução, na filtragem ou na aproximação usada pelo índice.
Resumo rápido
- Compare identificadores recuperados com uma referência exata e estável.
- Separe consultas por seletividade do filtro, não apenas por assunto.
- Ajuste parâmetros de busca antes de reconstruir índices.
- Inspecione o plano real e registre a versão instalada da extensão.
- Aprove uma configuração por qualidade e latência sob concorrência.
1. Defina o que uma busca boa precisa entregar
Recall, neste contexto, é a proporção dos vizinhos da referência exata que também aparecem no resultado aproximado. Para uma consulta cujo conjunto exato contém dez identificadores, encontrar oito deles representa recall de 0,8. Esse número é uma definição de avaliação, não um resultado esperado para determinada infraestrutura. Quando o filtro permite menos documentos que o limite solicitado, use o tamanho do conjunto exato como denominador.
Prepare um conjunto de perguntas representativo do uso real. Inclua consultas curtas, descrições longas, referências de produtos e mensagens com vocabulário pouco frequente. Para cada pergunta, armazene o vetor da consulta, os filtros, o limite de resultados e os identificadores esperados na busca exata. Empates de distância precisam de uma regra explícita de comparação, para que uma troca entre equivalentes não pareça falha de recuperação.
Congele a versão dos embeddings durante o experimento. Se a representação dos documentos mudar no meio do teste, você estará comparando sistemas diferentes. Separe qualidade do índice e qualidade semântica: recuperar os vizinhos exatos não significa que esses vizinhos respondem bem à pergunta. A avaliação de respostas com Ragas e TruLens cobre outra camada dessa decisão.
Como proposta prática, monte uma planilha com uma linha por pergunta e configuração. Registre recall, quantidade retornada, duração, filtro, plano escolhido e observações do avaliador. Uma média única esconde justamente os casos que costumam incomodar o atendimento: clientes pequenos, categorias raras e documentos recém-adicionados.
2. Leia o plano antes de escolher os parâmetros
Use EXPLAIN (ANALYZE, BUFFERS) em uma consulta representativa, num ambiente onde sua execução seja aceitável. O PostgreSQL documenta que ANALYZE, nessa forma, executa a instrução e acrescenta medidas reais ao plano. Examine o tipo de varredura, linhas estimadas versus observadas, filtros e acesso a buffers. A documentação de EXPLAIN explica como interpretar esses elementos.
Uma varredura sequencial não é automaticamente um defeito. Em uma tabela pequena ou em um subconjunto restrito, ela pode fazer parte de uma escolha razoável. Anote o plano observado antes de tentar obrigar o banco a usar um índice. O objetivo da aplicação é cumprir o orçamento de tempo com qualidade suficiente; o nome do nó no plano é evidência para investigar, não um indicador de sucesso isolado.
Confira também as estatísticas após uma carga relevante. O comando ANALYZE documentos atualiza informações usadas pelo planejador, conforme a referência oficial de ANALYZE. Atualizar estatísticas não reconstrói o grafo nem corrige embeddings inconsistentes. Isso evita misturar manutenção do planejamento com manutenção da representação vetorial.
Separe testes com cache aquecido e testes de primeira consulta. Registre concorrência e tamanho da resposta. Se uma execução devolve apenas identificadores e outra transporta documentos inteiros, a comparação de duração inclui diferenças alheias à busca. Mantenha a projeção da consulta igual nas variantes do experimento.
3. Ajuste HNSW e IVFFlat com hipóteses pequenas
HNSW organiza a busca por um grafo; IVFFlat organiza vetores em listas e consulta parte delas. Na comparação apresentada pelo projeto pgvector, HNSW usa mais memória e tem construção mais lenta, enquanto oferece uma relação favorável entre velocidade e recall. Esses compromissos orientam o teste, mas não substituem medições da sua carga.
| Decisão | HNSW | IVFFlat |
|---|---|---|
| Estrutura | Grafo de proximidade | Listas de vetores |
| Ajuste de consulta | hnsw.ef_search | ivfflat.probes |
| Ajuste de construção | m e ef_construction | lists |
| Pergunta experimental | Mais candidatos recuperam os itens ausentes? | Visitar mais listas resolve a perda observada? |
No HNSW, aumente hnsw.ef_search em etapas e observe a fronteira entre qualidade e tempo. No IVFFlat, faça o equivalente com ivfflat.probes. A documentação do pgvector descreve ambos como controles que trocam velocidade por recall. Mude uma variável por vez. Se aumentar o esforço não melhora o resultado, interrompa a escalada e investigue o filtro, os dados e a referência.
Garanta compatibilidade entre a distância da consulta e a classe de operadores do índice. A documentação de HNSW da Supabase relaciona distância de cosseno a vector_cosine_ops, por exemplo. Uma consulta ordenada por outra métrica não representa o mesmo experimento.
O IVFFlat deve ser construído com dados representativos. A referência de IVFFlat detalha sua dependência da distribuição dos vetores e a escolha das listas. Trate uma grande mudança no catálogo como motivo para repetir a avaliação. Não confunda crescer em quantidade com permanecer semelhante em distribuição.
4. Investigue filtros e resultados incompletos
Quando um índice aproximado é utilizado, candidatos podem ser descartados pelo filtro aplicado durante a recuperação. Assim, pedir dez resultados não garante receber dez. A documentação de HNSW da Supabase descreve esse efeito e as varreduras iterativas, disponíveis a partir do pgvector 0.8.0. No HNSW, strict_order preserva a ordenação por distância; limites de varredura ainda podem encerrar a busca antes de completar o conjunto.
Monte faixas de seletividade: consultas sem filtro, filtros amplos e filtros que deixam poucos documentos elegíveis. Para cada faixa, compare a quantidade devolvida com a referência exata. Essa separação permite descobrir se o problema é geral ou concentrado numa combinação de cliente e categoria. Não remova o filtro de autorização para melhorar números de recuperação.
Considere um índice convencional na coluna filtrada e compare o plano resultante. Outra possibilidade é um índice parcial para um subconjunto estável. O PostgreSQL exige que o planejador reconheça a relação entre o predicado da consulta e o do índice; a documentação de índices parciais também explica limitações envolvendo consultas parametrizadas.
Particionamento merece uma avaliação separada quando a divisão dos dados tem sentido operacional duradouro. Ele altera manutenção, distribuição e planejamento; não deve ser acrescentado apenas para melhorar um teste pontual. A documentação de particionamento do PostgreSQL é a referência para planejar essa estrutura.
5. Exemplo: central de peças industriais em Joinville
Considere uma distribuidora fictícia de Joinville que pesquisa manuais por descrição do defeito. Cada consulta também restringe o fabricante e a linha de equipamento. Este exemplo é ilustrativo: não descreve uma implantação nem apresenta ganhos medidos.
A equipe prepara perguntas revisadas por técnicos e mantém uma cópia estável da base para o ensaio. Primeiro identifica os vizinhos exatos sob cada filtro. Depois compara HNSW com diferentes esforços de busca. Em vez de aprovar pela média, examina separadamente fabricantes com poucos manuais. Se faltarem resultados apenas nesse grupo, o próximo experimento deverá tratar a filtragem.
O SQL abaixo ilustra um ajuste por transação. Pressupõe uma tabela existente, vetor com dimensão compatível e parâmetros fornecidos pelo driver. O valor 100 é experimental, não uma recomendação universal. A distância de cosseno corresponde ao operador <=>.
BEGIN;
SET LOCAL hnsw.ef_search = 100;
SELECT id
FROM documentos
WHERE fabricante_id = $1
ORDER BY embedding <=> $2::vector
LIMIT 10;
COMMIT;
Segundo a documentação de SET, SET LOCAL limita a alteração à transação. Na aplicação, garanta que as instruções usem a mesma conexão e que erros provoquem rollback. Acrescente ao relatório o parâmetro aplicado e a identidade do conjunto de teste, sem registrar conteúdo confidencial dos manuais.
Antes da implantação, a distribuidora repete a configuração candidata com várias sessões simultâneas e mede o tempo completo da pesquisa. Se o banco atende bem isoladamente, mas a aplicação demora, o próximo diagnóstico deverá incluir fila de conexões, transporte e processamento posterior. Um índice não resolve sozinho todos esses componentes.
Erros comuns
Otimizar apenas a melhor consulta. Escolher uma pergunta fácil e repetir até obter um tempo bonito produz uma configuração frágil. Mantenha o conjunto de validação separado das perguntas usadas nos ajustes. Inclua consultas que anteriormente falharam e registre por que cada uma entrou no teste.
Comparar referências diferentes. Mesmo filtro, mesma distância e mesma versão dos dados são condições mínimas. Se a busca exata enxerga documentos que o usuário não pode consultar, seu recall passa a medir outra coisa. Defina a população elegível antes de calcular qualquer proporção.
Reconstruir cedo demais. Reserve mudanças estruturais para hipóteses que os ajustes de consulta não resolveram. Documente tempo de construção, espaço necessário, procedimento de reversão e janela operacional. Um ganho pequeno de consulta pode não justificar o custo de manter outra estrutura.
Aplicar parâmetros globalmente sem revisar o pool. Use transações explícitas para ensaios por solicitação e teste o caminho de erro. Depois de uma exceção, a próxima requisição precisa continuar previsível. Esse detalhe é parte da qualidade operacional, mesmo quando o resultado vetorial parece correto.
Perguntas frequentes
HNSW sempre é a escolha certa?
Não há aprovação universal. Use-o como candidato e compare qualidade, memória, manutenção e concorrência no seu ambiente. A decisão deve incluir o custo de construção e atualização, além do tempo de uma consulta isolada.
Recall alto garante uma resposta correta?
Não. Ele indica proximidade com a referência da recuperação. Documentos inadequados, fragmentação ruim ou geração incorreta podem continuar produzindo respostas ruins. Avalie separadamente busca, seleção de contexto e resposta final.
Por que o banco ignora o índice?
Inspecione o plano, a métrica, a forma da consulta e as estatísticas. O planejador pode preferir outro caminho. Sem observar esses dados, forçar uma escolha apenas encobre o motivo e dificulta reproduzir o comportamento.
Devo aumentar parâmetros até atingir recall perfeito?
Defina antes a qualidade exigida pelo produto. Se a exigência for reproduzir integralmente a referência, inclua a busca exata entre as opções. Medir o custo dessa exigência é mais útil do que assumir que aproximação sempre será adequada.