Referência: Armazenamento RAG com pgvector
Referência composta para RAG de documentos em PostgreSQL 18.4 + pgvector 0.8+ (instância search dedicada, 64 GB RAM). ~40M chunks, embeddings de 1536 dimensões, SaaS multi-tenant com RLS.
Esquema
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE document_chunks (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
tenant_id uuid NOT NULL,
document_id uuid NOT NULL,
chunk_index int NOT NULL,
content text NOT NULL,
embedding vector(1536) NOT NULL,
created_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (tenant_id, document_id, chunk_index)
);
ALTER TABLE document_chunks ENABLE ROW LEVEL SECURITY;
CREATE POLICY chunks_tenant ON document_chunks
USING (tenant_id = current_setting('app.tenant_id', true)::uuid);Ajuste de Índice (HNSW)
CREATE INDEX document_chunks_embedding_hnsw_idx
ON document_chunks
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
-- Recall vs latência no momento da consulta
SET hnsw.ef_search = 100;| Parâmetro | Valor | Nota |
|---|---|---|
m | 16 | Equilíbrio padrão para 1536 dimensões |
ef_construction | 64 | Tempo de construção vs recall |
ef_search | 40-120 | Definido por requisição no app |
| Distância | vector_cosine_ops | Corresponde aos modelos de cosseno da OpenAI |
Padrão de Consulta
SELECT id, document_id, content,
embedding <=> $1::vector AS distance
FROM document_chunks
WHERE tenant_id = $2::uuid
ORDER BY embedding <=> $1::vector
LIMIT 20;- Sempre filtre
tenant_idantes da ordenação vetorial (RLS + planejador). - Índices parciais por tenant grande considerados acima de 5M de chunks.
- Escritas de embedding em lote;
COPYpara ingestão em massa fora do horário de pico.
Topologia
Primário OLTP (contas, faturamento)
│
└── Subconjunto de replicação lógica → Instância de busca (apenas chunks)Instância de busca dimensionada para RAM do HNSW (~2x de margem para o tamanho do índice). Manutenção de construção HNSW não co-localizada com OLTP.
Operações
- Reindexar HNSW na janela de manutenção após uma atualização importante do pgvector.
- Monitorar
idx_scane latência de busca p95 separadamente do SLO do OLTP. - Exclusão de tenant:
DELETE FROM document_chunks WHERE tenant_id = $1(job assíncrono).
Relacionados
- Noções Básicas de pgvector - introdução à extensão
- Índices IVFFlat vs HNSW - escolha de índice
- Esquema de Armazenamento RAG - profundidade do esquema
- Referência: SaaS Multi-Tenant - padrões RLS
Versões do Stack: Esta página foi escrita para PostgreSQL 18.4 (estável 18, manutenção 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x e PostGIS 3.5+.