pgvector: a busca vetorial em PostgreSQL
pgvector é uma extensão open source do PostgreSQL (licença PostgreSQL, permissiva) que adiciona o armazenamento e a busca de vetores a uma base que você já administra, com colunas indexáveis de até 2.000 dimensões (4.000 em meia precisão). Para um corpus local de algumas centenas de milhares de fragmentos, isso significa um serviço a menos para operar e filtros SQL que funcionam, sem uma sincronização a manter com seus dados relacionais.
pgvector é uma extensão do PostgreSQL que adiciona o armazenamento e a busca de vetores a um banco que você já administra. Para a maioria dos projetos de pesquisa documental local, é um serviço a menos para rodar, um backup a menos para organizar e filtros SQL que realmente funcionam — inclusive para os direitos de acesso. O projeto, mantido sob licença PostgreSQL e hospedado no GitHub, contava com mais de 23.000 estrelas no fim de setembro de 2026, na versão 0.8.6, compatível com PostgreSQL 13 e versões mais recentes.
#O argumento: não adicionar um serviço
Uma instalação local para trabalhar com documentos já executa um servidor de modelo, uma etapa de codificação e um sistema de armazenamento de documentos. Adicionar um banco de dados vetorial dedicado significa mais um contêiner, mais uma porta, mais um backup e mais um componente que pode ficar fora de sincronia com seus dados relacionais quando um documento for excluído.
Se o PostgreSQL já está presente — e, em uma aplicação de negócio, quase sempre está —, o pgvector elimina toda essa categoria de problemas. Seus trechos de texto ficam em uma tabela ao lado dos documentos de onde vieram, com chaves estrangeiras que os mantêm consistentes, e uma exclusão se propaga como você espera, sem uma tarefa de limpeza separada para escrever ou monitorar. O projeto também acrescenta busca exata e aproximada, vetores de precisão simples, de meia precisão, binários e esparsos, cinco distâncias (L2, produto escalar, cosseno, L1, Hamming, Jaccard), e herda gratuitamente a conformidade ACID, a recuperação para um instante específico e as junções do PostgreSQL.
#Como funciona na prática
Seus documentos, sua IA: um RAG local confiável para seus PDFs, notas e e-mails — sem enviar nada para a nuvem.
- Espaço online vitalício
- PDF + arquivos
- Atualizações vitalícias
Você armazena uma coluna de vetores ao lado das colunas habituais. Uma consulta ordena as linhas pela distância em relação ao vetor da pergunta e retorna as mais próximas. Três operadores de distância cobrem os casos comuns, e o que você escolher deve corresponder à convenção do modelo de embedding: essa escolha é a causa mais frequente de resultados medíocres que passam despercebidos. Para vetores normalizados com comprimento 1 (o caso dos modelos da OpenAI e da maioria dos modelos de embedding recentes), o produto escalar é o mais rápido de calcular e produz a mesma classificação que o cosseno.
| Elemento | O que é | O que observar |
|---|---|---|
| Coluna de vetor | Um array de números de ponto flutuante de dimensão fixa | A dimensão vem do modelo de embedding e não muda sem recodificar tudo |
| Operador de distância | Cosseno, produto escalar ou euclidiano (L2) | Deve corresponder ao modelo |
| Índice HNSW | Índice em grafo, consultas rápidas | Construção lenta e com alto consumo de memória; uma escolha padrão sensata desde a versão 0.5 |
| Índice IVFFlat | Índice por partições, de baixo custo de construção | Criar quando já houver dados representativos |
| Nenhum índice | Varredura exata de todas as linhas | Plenamente viável até algumas dezenas de milhares de linhas |
#O SQL mínimo para começar
- 01Ativar a extensãoCREATE EXTENSION IF NOT EXISTS vector; — um único comando, a ser executado uma vez por banco de dados.
- 02Adicionar a colunaALTER TABLE chunks ADD COLUMN embedding vector(1024); — a dimensão deve corresponder exatamente à do modelo de embedding utilizado.
- 03Carregar os dados antes de indexarUm carregamento em massa via COPY é mais rápido sem um índice existente; crie o índice quando já houver uma quantidade representativa de linhas.
- 04Criar o índiceCREATE INDEX CONCURRENTLY ON chunks USING hnsw (embedding vector_cosine_ops); — a opção CONCURRENTLY evita bloquear as operações de escrita durante a construção do índice, que é demorada em uma tabela grande.
- 05ConsultarSELECT contenu FROM chunks WHERE document_id IN (SELECT id FROM documents WHERE utilisateur_autorise($1)) ORDER BY embedding <=> $2 LIMIT 5; — filtro de autorização e ordenação por similaridade na mesma consulta.
#Os limites de dimensão, na prática
O pgvector define quatro tipos de colunas, cada um com seu próprio limite de dimensão indexável. O tipo vector padrão (precisão simples, 4 bytes por elemento) é indexável até 2 000 dimensões, o que cobre a maioria dos modelos de embedding open source comuns (384 a 1 024 dimensões). Um modelo mais largo, como o text-embedding-3-large da OpenAI, com 3 072 dimensões por padrão, excede esse limite: a solução documentada é reduzir a dimensão na geração do embedding (a API permite) ou migrar para o tipo halfvec, que armazena em meia precisão (2 bytes por elemento, metade do espaço) e é indexável até 4 000 dimensões. O tipo bit (vetores binários, distâncias de Hamming ou Jaccard) suporta até 64 000 dimensões indexáveis, e o sparsevec (vetores esparsos) até 1 000 elementos não nulos indexados — além disso, o PostgreSQL ainda armazena a coluna (até 16 000 dimensões para vector, halfvec e sparsevec), mas sem poder indexá-la, o que resulta em uma varredura exata.
#Filtragem e permissões de acesso
Uma pergunta real raramente abrange todo o corpus: queremos os trechos desse serviço, posteriores a essa data, nos documentos que esse usuário tem direito de ler. Em uma base vetorial dedicada, é um filtro de metadados com sua sintaxe e seus casos limites. No PostgreSQL, é uma cláusula WHERE junto de uma ordenação por similaridade, com uma junção à sua tabela de usuários, se necessário.
Uma armadilha documentada pelo próprio projeto merece ser conhecida antes de você se deparar com ela em produção: com um índice aproximado (HNSW ou IVFFlat), o filtro é aplicado após a varredura do índice, não antes. Se uma condição retém apenas 10% das linhas e o parâmetro padrão hnsw.ef_search vale 40, apenas 4 linhas em média são retornadas — não as dez solicitadas. A solução oficial, disponível desde a versão 0.8.0, chama-se varredura iterativa do índice (SET hnsw.iterative_scan = strict_order), que repete automaticamente a varredura até encontrar resultados suficientes, em vez de retornar silenciosamente um conjunto truncado.
#Onde estão os limites
- Memória em grande escala
- Milhões de vetores em precisão total ocupam muito espaço; halfvec e a quantização binária reduzem o uso de memória, mas os mecanismos dedicados conseguem comprimir ainda mais de forma nativa. Essa é a diferença mais clara.
- Tempo de construção do índice
- Construir um índice HNSW em uma tabela muito grande demora e consome muitos recursos; em produção, construí-lo com CREATE INDEX CONCURRENTLY evita bloquear as escritas durante a operação.
- A concorrência
- Executar buscas vetoriais pesadas junto com sua carga transacional coloca ambas no mesmo servidor. Réplicas de leitura ajudam; separar as funções ajuda ainda mais.
- A dimensão dos vetores
- Os vetores indexados têm um limite conforme seu tipo (2.000 para vector, 4.000 para halfvec). Os modelos comuns ficam dentro desses limites; um modelo com dimensionalidade muito alta deve ser reduzido ou quantizado.
- A pesquisa híbrida
- PostgreSQL suporta busca de texto completo (tsvector) e você pode combiná-la com a distância vetorial, mas cabe a você tornar esse processo prático: é necessário executar as duas consultas separadamente e depois fundir as classificações, por exemplo usando fusão de rankings recíprocos (Reciprocal Rank Fusion), em vez de obter uma pontuação híbrida nativa em uma única consulta.
- A escalabilidade horizontal
- Para ir além de um único servidor, o caminho documentado passa por réplicas de leitura do PostgreSQL ou por uma ferramenta de distribuição como Citus ou PgDog — um componente a mais, contrariando o argumento inicial.
#pgvector ou uma base dedicada
A pergunta não é qual é objetivamente melhor, mas qual se encaixa na sua situação hoje. O pgvector leva vantagem quando o PostgreSQL já é a fonte de verdade da aplicação: faturamento, contas, documentos-fonte. Um mecanismo dedicado leva vantagem quando o volume de vetores ou a taxa de requisições ultrapassa o que um único servidor transacional consegue absorver sem prejudicar o restante da aplicação, ou quando a equipe prefere isolar o componente de IA do restante do sistema de informação por razões operacionais, em vez de razões puramente ligadas ao desempenho.
| Situação | Escolha |
|---|---|
| PostgreSQL já em uso, menos de algumas centenas de milhares de trechos | pgvector, confortavelmente |
| Os vetores devem permanecer coerentes com dados relacionais | pgvector: as transações fazem isso sem custo adicional |
| Filtragem granular com base nas permissões de acesso existentes | pgvector |
| Modelo de embedding com mais de 4.000 dimensões sem possibilidade de redução | Verificar o tipo sparsevec ou um banco de dados dedicado pensado para esse caso |
| Milhões de vetores, muitas consultas | Um motor dedicado (Qdrant, Milvus) |
| Protótipo em um caderno de anotações | Qualquer um, essa escolha é reversível |
- Qdrant: a base vetorial dedicada
- Milvus, quando o volume ultrapassa o que o pgvector suporta
- FAISS: a biblioteca por trás da busca vetorial
- Construir a cadeia RAG completa
- Escolher o modelo de embedding
- O kit RAG local QuelLLM: todos os componentes em uma página
- Fonte: repositório oficial pgvector no GitHub
- Fonte: documentação dos índices e tipos pgvector
- Fonte: guia de escalabilidade pgvector
#FAQ
O pgvector é rápido o suficiente para RAG?+
pgvector ou Qdrant?+
Qual índice escolher, HNSW ou IVFFlat?+
Posso filtrar por metadados?+
O que acontece se eu mudar o modelo de embedding?+
Meu modelo de embedding tem mais de 2.000 dimensões, o que fazer?+
Como diagnosticar uma consulta vetorial lenta?+
Um comentário, um erro ou uma observação? Avise-nos; isso ajuda a melhorar o guia para todos.