Noções Básicas de pgvector
pgvector adiciona um tipo vector e operadores de distância ao PostgreSQL para armazenamento de embeddings e busca por similaridade. Instale a extensão, escolha uma métrica de distância e entenda os limites de dimensão antes de construir índices RAG.
Receita
CREATE EXTENSION IF NOT EXISTS vector WITH SCHEMA extensions VERSION '0.8.0';
CREATE TABLE embeddings (
id bigserial PRIMARY KEY,
label text NOT NULL,
embedding extensions.vector(3) -- dimensão fixada no momento do DDL
);
INSERT INTO embeddings (label, embedding) VALUES
('postgres', '[1,2,3]'),
('vectors', '[2,3,4]');
-- Operadores de distância (use a opclass de índice correspondente)
SELECT label,
embedding <-> '[1,2,3]'::extensions.vector AS l2_distance,
embedding <=> '[1,2,3]'::extensions.vector AS cosine_distance,
embedding <#> '[1,2,3]'::extensions.vector AS inner_product_neg
FROM embeddings
ORDER BY embedding <=> '[1,2,3]'::extensions.vector
LIMIT 5;Quando usar isso: Busca semântica, recuperação RAG, recomendações ou deduplicação onde embeddings já existem de um modelo upstream.
Exemplo de Trabalho
CREATE TABLE documents (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
title text,
embedding extensions.vector(1536) -- OpenAI text-embedding-3-small
);
INSERT INTO documents (title, embedding)
VALUES (
'Vacuum and bloat',
(SELECT array_agg(random())::float[]::extensions.vector FROM generate_series(1, 1536))
);
-- Vizinho mais próximo exato (sem índice; bom para tabelas pequenas)
SELECT id, title, embedding <=> (
SELECT embedding FROM documents LIMIT 1
) AS distance
FROM documents
ORDER BY distance
LIMIT 10;O que isso demonstra:
- A dimensão faz parte do tipo (
vector(1536)) - Vetores são inseridos como literais de string
'[...]'ou convertidos de arrays <=>é a distância cosseno para embeddings normalizados- A varredura exata é a linha de base antes dos índices IVFFlat ou HNSW
Mergulho Profundo
Operadores de Distância
| Operador | Métrica | Opclass de Índice | Uso Típico |
|---|---|---|---|
<-> | L2 (Euclidiana) | vector_l2_ops | Espaços de embedding brutos |
<=> | Distância Cosseno | vector_cosine_ops | Embeddings de texto normalizados |
<#> | Produto interno negativo | vector_ip_ops | Busca de produto interno máximo |
Regra: O operador de consulta deve corresponder à opclass do índice. Uma coluna indexada com cosseno e um operador L2 retornam a ordenação incorreta ou nenhum índice.
Limites de Tipo
- Máximo de dimensões: 2000 para o tipo
vectorno pgvector 0.8+ (verifique as notas de lançamento para sua versão fixada). - Armazenamento:
4 * dimensõesbytes por vetor (float32) mais sobrecarga do heap. halfvecde meia precisão (quando habilitado em sua compilação) reduz o armazenamento para grandes corpora.
SELECT typname, typlen FROM pg_type WHERE typname = 'vector';
-- Valida a dimensão na inserção
ALTER TABLE documents
ADD CONSTRAINT embedding_dim CHECK (vector_dims(embedding) = 1536);Funções
SELECT vector_dims(embedding), vector_norm(embedding) FROM documents LIMIT 1;
-- Aritmética elemento a elemento
SELECT embedding + '[0.1,0.2,0.3]'::extensions.vector FROM embeddings WHERE id = 1;Quando usar Postgres vs Banco de Dados Vetorial Dedicado
Postgres + pgvector vence quando:
- Os dados já residem no Postgres com atualizações transacionais
- O corpus cabe em uma única instância com ajuste HNSW
- A equipe não pode operar outro sistema distribuído
Considere bancos de dados vetoriais dedicados quando escala de bilhões, sub-10ms com QPS alto, ou um DSL de filtragem avançado for obrigatório e provar ser caro em SQL.
Armadilhas
- Opclass incorreta - HNSW construído com
vector_l2_opsmas as consultas usam<=>. Correção: Reconstrua o índice comvector_cosine_opspara corresponder às consultas. - Discrepância de dimensão - Mudança de modelo de 1536 para 3072 sem migração. Correção: Nova coluna ou tabela; re-incorpore tudo; versão do modelo de embedding nos metadados.
- Cosseno não normalizado - A distância cosseno em vetores de norma zero tem comportamento indefinido. Correção:
CHECK (vector_norm(embedding) > 0)ou normalize na inserção no aplicativo. - Construção de strings de embeddings em SQL - Injeção e erros de análise. Correção: Vincule parâmetros do driver do aplicativo.
- Sem índice em tabela grande - Varredura sequencial ordena milhões de linhas por consulta. Correção: IVFFlat ou HNSW após testes de busca exata de linha de base.
- Extensão não em search_path -
type vector does not exist. Correção: Qualifique o esquemaextensions.vectorou adicione o esquema aosearch_pathapenas para a função do aplicativo.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Índice IVFFlat | Tabela grande, restrição de memória | Necessita do maior recall pronto para uso |
| Índice HNSW | Padrão ANN de produção em 0.8+ | Não pode arcar com a RAM de construção do índice |
| Pinecone/Weaviate Externo | Escala massiva, ANN gerenciado | Junções FK fortes com dados relacionais |
pg_trgm FTS | Palavra-chave exata | Paráfrase semântica |
FAQs
Instalar no RDS/Aurora?
Verifique a lista de extensões da AWS para sua versão do motor. Fixe a versão do `vector` na lista de permissões do grupo de parâmetros.Halfvec vs vector?
halfvec economiza espaço quando o modelo suporta float16; verifique o suporte do índice em sua versão fixada do pgvector.Embeddings nulos?
Permita NULL para trabalhos de incorporação pendentes; índice parcial `WHERE embedding IS NOT NULL`.Atualizar embedding?
A atualização da linha aciona a manutenção do índice; re-incorpore em lote fora do pico.Cosseno vs produto interno?
Para vetores normalizados, a distância cosseno e o produto interno classificam de forma semelhante; escolha um e mantenha a consistência.Consultas paralelas?
Aumente `max_parallel_workers_per_gather` para força bruta; HNSW usa principalmente varredura de índice de thread única.Array JSON para vetor?
Converta na camada do aplicativo; o padrão `array_agg` do SQL funciona apenas para testes.pgvector em replicação lógica?
Replique os dados da tabela; garanta que o assinante tenha a mesma versão da extensão.Tamanho do backup?
Vetores inflacionam backups; monitore amostras de `pg_column_size(embedding)`.Próximo passo?
Artigo IVFFlat vs HNSW para escolha de índice.Relacionados
- Índices IVFFlat vs HNSW - Compromissos do índice ANN
- Esquema de Armazenamento RAG - tabelas de chunk
- Busca Híbrida - palavra-chave + vetor
- Noções Básicas de Extensões - instalar e fixar versão
- Melhores Práticas do pgvector - benchmarking de recall
Versões da Pilha: Esta página foi escrita para PostgreSQL 18.4 (estável 18, manutenção 17), pgvector 0.8+, PostGIS 3.5+, pgbouncer 1.x e Patroni 3.x.