pgvector: Búsqueda vectorial en PostgreSQL
Qué cubre este artículo
- Qué es pgvector y por qué es una extensión de PostgreSQL para búsqueda vectorial.
- Cómo instalar pgvector y usar el tipo de dato
vector. - Qué tipos de índice existen y cuándo elegir IVFFlat o HNSW.
- Cómo almacenar y consultar vectores en SQL.
- Dónde se posiciona pgvector frente a Chroma y Qdrant.
Introducción
Si ya usas PostgreSQL en tu proyecto, no necesitas una nueva base de datos vectorial. pgvector es una extensión de PostgreSQL que permite búsqueda vectorial directamente en tu base de datos existente. Almacenas embeddings junto con tus datos de tablas normales y los consultas con SQL. Esto reduce la infraestructura y simplifica tu stack considerablemente. Este artículo te muestra cómo instalar pgvector, almacenar vectores y realizar búsquedas de similitud.
¿Por qué necesito pgvector?
Muchos proyectos ya usan PostgreSQL para datos de usuarios, documentos o configuraciones. Cuando quieres añadir RAG, enfrentas una decisión: instalar una base de datos vectorial adicional como Chroma o Qdrant, o integrar la búsqueda vectorial en PostgreSQL. pgvector hace lo segundo posible. La mayor ventaja es que mantienes vectores y datos normales en la misma base de datos. Puedes escribir consultas con JOIN que vinculen resultados vectoriales con metadatos de otras tablas. Esto es más engorroso con bases de datos vectoriales dedicadas.
pgvector se adapta especialmente bien si tu conjunto de vectores tiene desde algunos miles hasta algunos millones de entradas. Para conjuntos de datos extremadamente grandes o requisitos especiales como aceleración GPU, las soluciones dedicadas suelen ser mejores.
pgvector en pocas palabras
pgvector añade a PostgreSQL un nuevo tipo de dato llamado vector. Defines columnas con este tipo, almacenas embeddings como listas de números y usas operadores especiales para búsqueda de similitud. Los operadores principales son:
<->para distancia L2 (Euclidean Distance)<#>para Inner Product<=>para Cosine Similarity
Además, pgvector ofrece dos tipos de índice para acelerar la búsqueda con grandes volúmenes de datos: IVFFlat y HNSW. Ambos son procedimientos Approximate Nearest Neighbor (ANN) que reducen el tiempo de búsqueda al comparar solo candidatos prometedores en lugar de cada vector.
¿Para quién es este artículo?
Este artículo va dirigido a desarrolladores y administradores que ya usan PostgreSQL y quieren añadir capacidades RAG. Deberías tener conocimientos básicos de SQL y saber qué son los embeddings. Si eres completamente nuevo en bases de datos vectoriales, primero lee el artículo de descripción general sobre bases de datos vectoriales y el artículo sobre modelos de embedding.
Términos importantes
| Término | Significado |
|---|---|
vector | Tipo de dato en pgvector para embeddings, por ejemplo vector(768) |
| Embedding | Vector numérico que codifica el significado de un texto |
| Cosine Similarity | Medida de similitud sobre el ángulo entre dos vectores |
| L2 Distance | Distancia euclidiana entre dos vectores |
| IVFFlat | Tipo de índice que divide el espacio en clusters (Inverted File) |
| HNSW | Tipo de índice con grafo jerárquico (Hierarchical Navigable Small World) |
| ANN | Approximate Nearest Neighbor, búsqueda aproximada para velocidad |
| Extension | Extensión de PostgreSQL que añade nuevos tipos de dato y funciones |
Instalación
pgvector con Docker
La forma más sencilla es usar una imagen Docker que ya incluya pgvector. Más información sobre Docker en el artículo Fundamentos de Docker.
docker run -d \
--name pgvector-db \
-e POSTGRES_PASSWORD=deinpasswort \
-e POSTGRES_DB=vektoren \
-p 5432:5432 \
pgvector/pgvector:pg16
pgvector en un PostgreSQL existente
Si ya tienes PostgreSQL instalado, compila pgvector desde el código fuente:
git clone https://github.com/pgvector/pgvector.git
cd pgvector
make
make install
Luego activa la extensión en PostgreSQL:
CREATE EXTENSION IF NOT EXISTS vector;
Primeros pasos
Crear una tabla con columna vectorial
CREATE TABLE dokumente (
id SERIAL PRIMARY KEY,
titel TEXT,
inhalt TEXT,
quelle TEXT,
embedding VECTOR(768)
);
El número en VECTOR(768) debe coincidir con la dimensión de tu modelo de embedding. Si usas multilingual-e5-large, son 1024 dimensiones.
Insertar vectores
INSERT INTO dokumente (titel, inhalt, quelle, embedding)
VALUES (
'Was ist lokale KI',
'Lokale KI läuft auf dem eigenen Rechner.',
'blog',
'[0.1, 0.2, 0.3, 0.4]'
);
En la práctica, generas los embeddings con Python y luego los insertas. La lista de vectores se pasa como texto entre corchetes.
Búsqueda de similitud
SELECT titel, quelle, embedding <=> '[0.1, 0.2, 0.3, 0.4]' AS distanz
FROM dokumente
ORDER BY embedding <=> '[0.1, 0.2, 0.3, 0.4]'
LIMIT 5;
El operador <=> calcula la Cosine Similarity. Cuanto menor sea el valor, más similares son los vectores. Ordenas ascendentemente y tomas los primeros resultados.
Tipos de índice: IVFFlat vs. HNSW
Sin índice, PostgreSQL busca cada vector secuencialmente. Esto se vuelve lento con varios cientos de miles de entradas. Un índice acelera la búsqueda significativamente.
Índice IVFFlat
IVFFlat divide el espacio vectorial en clusters. Durante la búsqueda, solo se explora el cluster que se ajusta al vector de consulta.
CREATE INDEX idx_dokumente_ivfflat
ON dokumente
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
El parámetro lists determina el número de clusters. Una buena regla es rows / 1000. Debes reconstruir el índice después de insertar datos para que los centros de los clusters se elijan bien.
Índice HNSW
HNSW construye un grafo jerárquico. Es a menudo más rápido y preciso que IVFFlat en consultas, pero requiere más memoria y tiempo de construcción.
CREATE INDEX idx_dokumente_hnsw
ON dokumente
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
El parámetro m controla las conexiones del grafo, ef_construction la calidad de la construcción. Para la búsqueda puedes ajustar ef_search:
SET hnsw.ef_search = 100;
¿Qué índice debo elegir?
HNSW es la mejor opción en la mayoría de los casos. Ofrece mayor precisión con velocidad comparable. IVFFlat es más simple de entender y requiere menos memoria. Si comienzas desde cero, usa HNSW. Si ya tienes un índice IVFFlat y estás satisfecho, mantente con él.
Usar pgvector con Python
import psycopg2
from pgvector.psycopg2 import register_vector
conn = psycopg2.connect("dbname=vektoren user=postgres password=deinpasswort")
register_vector(conn)
cur = conn.cursor()
cur.execute("CREATE EXTENSION IF NOT EXISTS vector")
cur.execute("""
CREATE TABLE IF NOT EXISTS dokumente (
id SERIAL PRIMARY KEY,
titel TEXT,
embedding VECTOR(768)
)
""")
# Embedding de tu modelo
embedding = [0.1] * 768
cur.execute(
"INSERT INTO dokumente (titel, embedding) VALUES (%s, %s)",
("Lokale KI", embedding)
)
cur.execute("""
SELECT titel, embedding <=> %s AS distanz
FROM dokumente
ORDER BY embedding <=> %s
LIMIT 5
""", (embedding, embedding))
results = cur.fetchall()
for row in results:
print(row)
conn.commit()
cur.close()
conn.close()
Comparación con Chroma y Qdrant
| Propiedad | pgvector | Chroma | Qdrant |
|---|---|---|---|
| Tipo | Extensión de PostgreSQL | Base de datos vectorial independiente | Base de datos vectorial independiente |
| Configuración | Simple si tienes Postgres | Muy simple vía pip | Simple vía Docker |
| Soporte SQL | Completo | No | No |
| Joins con datos tabulares | Sí | No | No |
| Escalabilidad | Media | Pequeña a media | Alta |
| Filtrado | Completo (SQL WHERE) | Simple | Avanzado (Payload) |
| Tipos de índice | IVFFlat, HNSW | HNSW | HNSW |
| Soporte GPU | No | No | No |
| Requisitos de almacenamiento | Medio | Bajo | Medio |
pgvector destaca cuando ya usas PostgreSQL y necesitas combinar vectores con datos relacionales. Para búsqueda de vectores puros con grandes volúmenes de datos, Chroma y Qdrant suelen ser la mejor opción. Más información sobre la combinación de diferentes métodos de búsqueda la encontrarás en el artículo sobre Hybrid Search.
Errores comunes
- Dimensión de vector incorrecta: La definición de columna
VECTOR(768)debe coincidir exactamente con la dimensión de tu modelo de embedding. Un modelo con 1024 dimensiones no funcionará en una columna de 768 dimensiones. - Sin índice para grandes volúmenes: Sin IVFFlat o HNSW, las búsquedas se vuelven muy lentas a partir de decenas de miles de registros. Crea el índice antes de usar la base de datos en producción.
- Índice IVFFlat creado antes de insertar datos: IVFFlat calcula los centros de clústers durante la construcción del índice. Si la tabla está vacía, los clústers serán deficientes. Inserta los datos primero y luego crea el índice.
- Clase de operador incorrecta: Cada medida de distancia requiere su propia clase de operador, por ejemplo
vector_cosine_opspara Cosine Similarity. Una clase incorrecta provoca errores o resultados erróneos. work_meminsuficiente: Las construcciones de HNSW necesitan memoria de trabajo. Con tablas grandes, aumentawork_memtemporalmente, por ejemplo a1GB.- Extensión olvidada: Después de actualizar o restaurar PostgreSQL, debes ejecutar
CREATE EXTENSION vectornuevamente, de lo contrario las funciones vectoriales no estarán disponibles. - Embeddings guardados como texto: Siempre guarda vectores como tipo
vector, no como texto o JSON. Solo así funcionan los operadores de similitud y los índices. - Sin mantenimiento con VACUUM: Como con cualquier tabla de PostgreSQL, los ciclos regulares de
VACUUMyANALYZEson importantes para que el optimizador de consultas cree planes adecuados.
Hardware, costos y seguridad
pgvector funciona en cualquier máquina que sea compatible con PostgreSQL. Para proyectos pequeños, un escritorio normal o un VPS pequeño es suficiente. Con varios millones de vectores, asegúrate de tener RAM adecuada, ya que los índices HNSW se mantienen en memoria. Se recomienda usar SSD, especialmente durante la construcción de índices.
Costos: pgvector es Open Source y gratuito. Solo pagas por el hardware o el servidor en el que corre PostgreSQL.
Seguridad: Dado que pgvector está integrado en PostgreSQL, se aplican las mismas reglas de seguridad. Usa contraseñas fuertes, limita el acceso a la red y habilita SSL para las conexiones. Si ejecutas pgvector en Docker, no expongas el puerto públicamente. Más información sobre operación segura con Docker la encontrarás en Docker Grundlagen.
Enlaces relacionados
- pgvector GitHub Repository
- pgvector Dokumentation
- Übersicht Vektordatenbanken
- RAG Grundlagen
- Lokales RAG
- Embedding-Modelle
- Chroma einrichten
- Qdrant einrichten
- Hybrid Search
- Docker Grundlagen
FAQ
¿Necesito una base de datos vectorial separada si uso pgvector?
No. pgvector extiende PostgreSQL con búsqueda de vectores. Si ya tienes PostgreSQL, no necesitas una base de datos adicional.
¿Qué versión de PostgreSQL es compatible?
pgvector es compatible con PostgreSQL 13 y versiones posteriores. Actualmente se soportan oficialmente las versiones 13 a 17.
¿Cuántos vectores puede gestionar pgvector?
Hasta varios millones de vectores funcionan bien con un índice HNSW. Por encima de eso, los requisitos de memoria se convierten en el factor limitante.
¿Debo usar IVFFlat o HNSW?
HNSW es la mejor opción en la mayoría de los casos, ya que ofrece mayor precisión con velocidad comparable. IVFFlat es más simple y eficiente en memoria.
¿Puedo usar pgvector con Python?
Sí. Existen bindings oficiales para psycopg2, psycopg3, SQLAlchemy y asyncpg. La biblioteca se llama pgvector-python.
¿Funciona pgvector con Docker?
Sí. Hay una imagen Docker oficial bajo pgvector/pgvector. También puedes construir tu propia imagen que instale pgvector en una imagen base de PostgreSQL.
¿Qué medidas de distancia soporta pgvector?
L2 Distance (Euclidiana), Inner Product y Cosine Similarity. Cada medida tiene su propio operador y su propia clase de operador de índice.
¿Puedo vincular vectores con datos de tablas normales?
Sí, esta es una de las mayores ventajas de pgvector. Puedes escribir consultas JOIN que combinen resultados de vectores con datos de otras tablas.
¿Cuánta memoria requiere un índice HNSW?
Depende de la dimensión del vector y del número de registros. Con 768 dimensiones y 1 millón de vectores, el índice puede alcanzar varios gigabytes.
¿Es pgvector gratuito?
Sí, pgvector es Open Source bajo la licencia PostgreSQL y es gratuito. Solo pagas por el hardware.
¿Puedo combinar pgvector con Ollama?
Sí. Ollama proporciona el modelo de lenguaje, pgvector almacena los embeddings. Tu script de Python conecta ambos a través de la conexión de base de datos.
¿Necesito reconstruir el índice después de cambios grandes de datos?
Los índices HNSW se actualizan automáticamente. Con cambios muy grandes, una reconstrucción puede mejorar la calidad. Los índices IVFFlat deben reconstruirse después de cambios grandes.
Fuentes
- pgvector GitHub Repository
- pgvector Python Bindings
- PostgreSQL Dokumentation
- HNSW Paper von Malkov und Yashunin
- IVFFlat Erklärung in der pgvector README


