Skip to content
BotServBotServ
pgvectorPostgreSQLbase de datos vectorialRAGIVFFlatHNSWIA local

pgvector: Búsqueda vectorial en PostgreSQL

pgvector como extensión PostgreSQL para bases de datos vectoriales. Instalación, tipos de índices y uso en RAG.

S

schutzgeist

9 min read
pgvector: Búsqueda vectorial en PostgreSQL

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érminoSignificado
vectorTipo de dato en pgvector para embeddings, por ejemplo vector(768)
EmbeddingVector numérico que codifica el significado de un texto
Cosine SimilarityMedida de similitud sobre el ángulo entre dos vectores
L2 DistanceDistancia euclidiana entre dos vectores
IVFFlatTipo de índice que divide el espacio en clusters (Inverted File)
HNSWTipo de índice con grafo jerárquico (Hierarchical Navigable Small World)
ANNApproximate Nearest Neighbor, búsqueda aproximada para velocidad
ExtensionExtensió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

PropiedadpgvectorChromaQdrant
TipoExtensión de PostgreSQLBase de datos vectorial independienteBase de datos vectorial independiente
ConfiguraciónSimple si tienes PostgresMuy simple vía pipSimple vía Docker
Soporte SQLCompletoNoNo
Joins con datos tabularesSíNoNo
EscalabilidadMediaPequeña a mediaAlta
FiltradoCompleto (SQL WHERE)SimpleAvanzado (Payload)
Tipos de índiceIVFFlat, HNSWHNSWHNSW
Soporte GPUNoNoNo
Requisitos de almacenamientoMedioBajoMedio

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_ops para Cosine Similarity. Una clase incorrecta provoca errores o resultados erróneos.
  • work_mem insuficiente: Las construcciones de HNSW necesitan memoria de trabajo. Con tablas grandes, aumenta work_mem temporalmente, por ejemplo a 1GB.
  • Extensión olvidada: Después de actualizar o restaurar PostgreSQL, debes ejecutar CREATE EXTENSION vector nuevamente, 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 VACUUM y ANALYZE son 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

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

Volver al blog
Share:

Entradas relacionadas