Conceptos básicos de pgvector
pgvector añade un tipo vector y operadores de distancia a PostgreSQL para el almacenamiento de embeddings y la búsqueda de similitud. Instala la extensión, elige una métrica de distancia y comprende los límites de dimensiones antes de construir índices RAG.
Receta
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) -- dimensión fija en el momento del DDL
);
INSERT INTO embeddings (label, embedding) VALUES
('postgres', '[1,2,3]'),
('vectors', '[2,3,4]');
-- Operadores de distancia (usa la opclass de índice coincidente)
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;Cuándo usar esto: Búsqueda semántica, recuperación RAG, recomendaciones o deduplicación donde los embeddings ya existen de un modelo anterior.
Ejemplo funcional
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))
);
-- Vecino más cercano exacto (sin índice; bien para tablas pequeñas)
SELECT id, title, embedding <=> (
SELECT embedding FROM documents LIMIT 1
) AS distance
FROM documents
ORDER BY distance
LIMIT 10;Lo que esto demuestra:
- La dimensión es parte del tipo (
vector(1536)) - Los vectores se insertan como literales de cadena
'[...]'o se convierten desde arrays <=>es la distancia coseno para embeddings normalizados- El escaneo exacto es la línea base antes de los índices IVFFlat o HNSW
Profundización
Operadores de Distancia
| Operador | Métrica | Opclass de índice | Uso típico |
|---|---|---|---|
<-> | L2 (Euclidiana) | vector_l2_ops | Espacios de embedding brutos |
<=> | Distancia coseno | vector_cosine_ops | Embeddings de texto normalizados |
<#> | Producto interior negativo | vector_ip_ops | Búsqueda de producto interior máximo |
Regla: El operador de consulta debe coincidir con la opclass del índice. Una columna indexada con coseno y un operador L2 devuelven un orden incorrecto o no usan el índice.
Límites del Tipo
- Dimensiones máximas: 2000 para el tipo
vectoren pgvector 0.8+ (consulta las notas de la versión para tu versión fijada). - Almacenamiento:
4 * dimensionesbytes por vector (float32) más sobrecarga del heap. halfvecde media precisión (cuando está habilitado en tu compilación) reduce el almacenamiento para corpus grandes.
SELECT typname, typlen FROM pg_type WHERE typname = 'vector';
-- Validar dimensión en la inserción
ALTER TABLE documents
ADD CONSTRAINT embedding_dim CHECK (vector_dims(embedding) = 1536);Funciones
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;Cuándo usar Postgres vs. Base de Datos Vectorial Dedicada
Postgres + pgvector gana cuando:
- Los datos ya residen en Postgres con actualizaciones transaccionales
- El corpus cabe en una instancia con ajuste HNSW
- El equipo no puede operar otro sistema distribuido
Considera bases de datos vectoriales dedicadas cuando se necesiten miles de millones de escalas, sub-10ms a un QPS muy alto, o un DSL de filtrado avanzado y resulte costoso en SQL.
Errores comunes
- Opclass incorrecta - HNSW construido con
vector_l2_opspero las consultas usan<=>. Solución: Reconstruye el índice convector_cosine_opspara que coincida con las consultas. - Desajuste de dimensiones - Cambio de modelo de 1536 a 3072 sin migración. Solución: Nueva columna o tabla; re-embebe todo; versiona el modelo de embedding en metadatos.
- Coseno no normalizado - La distancia coseno en vectores de norma cero es un comportamiento indefinido. Solución:
CHECK (vector_norm(embedding) > 0)o normaliza en la inserción en la aplicación. - Construcción de embeddings como cadenas en SQL - Inyección y errores de análisis. Solución: Vincula parámetros desde el controlador de la aplicación.
- Sin índice en tabla grande - Escaneo secuencial ordena millones de filas por consulta. Solución: IVFFlat o HNSW después de pruebas de búsqueda exacta de línea base.
- Extensión no en search_path -
type vector does not exist. Solución: Califica el esquemaextensions.vectoro añade el esquema asearch_pathsolo para el rol de la aplicación.
Alternativas
| Alternativa | Usar cuando | No usar cuando |
|---|---|---|
| Índice IVFFlat | Tabla grande, memoria limitada | Necesitas el mayor recall de inmediato |
| Índice HNSW | Predeterminado ANN de producción en 0.8+ | No puedes permitirte la RAM para construir el índice |
| Pinecone/Weaviate externos | Escala masiva, ANN gestionado | Uniones FK fuertes con datos relacionales |
pg_trgm FTS | Palabras clave exactas | Paráfrasis semántica |
Preguntas frecuentes
¿Instalar en RDS/Aurora?
Consulta la lista de extensiones de AWS para tu versión del motor. Fija la versión de `vector` en la lista blanca del grupo de parámetros.¿halfvec vs vector?
halfvec ahorra espacio cuando el modelo soporta float16; verifica el soporte de índices en tu versión fijada de pgvector.¿Embeddings nulos?
Permite NULL para trabajos de embebición pendientes; índice parcial `WHERE embedding IS NOT NULL`.¿Actualizar embedding?
UPDATE de fila activa el mantenimiento del índice; re-embebe en lote fuera de horas pico.¿Coseno vs producto interior?
Para vectores normalizados, la distancia coseno y el producto interior se clasifican de manera similar; elige uno y mantén la coherencia.¿Consultas paralelas?
Aumenta `max_parallel_workers_per_gather` para fuerza bruta; HNSW usa principalmente escaneo de índice de un solo hilo.¿Array JSON a vector?
Convierte en la capa de la aplicación; el patrón `array_agg` de SQL solo funciona para pruebas.¿pgvector en replicación lógica?
Replica los datos de la tabla; asegúrate de que el suscriptor tenga la misma versión de extensión.¿Tamaño de copia de seguridad?
Los vectores inflan las copias de seguridad; monitoriza muestras de `pg_column_size(embedding)`.¿Próximo paso?
Artículo IVFFlat vs HNSW para la elección del índice.Relacionados
- Índices IVFFlat vs HNSW - Compromisos de los índices ANN
- Esquema de Almacenamiento RAG - tablas de fragmentos
- Búsqueda Híbrida - palabras clave + vector
- Conceptos básicos de extensiones - instalación y fijación de versión
- Mejores prácticas de pgvector - benchmarking de recall
Versiones de la pila: Esta página fue escrita para PostgreSQL 18.4 (estable 18, mantenimiento 17), pgvector 0.8+, PostGIS 3.5+, pgbouncer 1.x, y Patroni 3.x.