~/tools / Embeddings y búsqueda (RAG) / pgvector SQL Builder
pgvector SQL Builder — Escribe SQL de pgvector: tabla, índice HNSW/IVFFlat y consulta de vecinos
Escribe el SQL para guardar y buscar embeddings en PostgreSQL con pgvector: una tabla con una columna vector(n) o halfvec(n), un índice HNSW o IVFFlat con la clase de operador que corresponde a tu distancia y una consulta de vecinos más cercanos con una puntuación legible. Comprueba los límites indicados en la documentación de pgvector y estima cuánto espacio ocupan los vectores. Nada sale de tu navegador.
Cada vector ocupa 1,544 bytes, así que 10,000 filas ocupan unos 15.4 MB solo con los vectores (sin contar los índices ni otras columnas).
1. Extensión y tabla
CREATE EXTENSION IF NOT EXISTS vector; CREATE TABLE documents ( id bigserial PRIMARY KEY, content text NOT NULL, embedding vector(384) NOT NULL );
2. Índice
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);
3. Búsqueda
PREPARE recibe como $1 el vector de la pregunta obtenido de /api/embed. Pásalo como texto, por ejemplo '[0.01,-0.02,…]'.
PREPARE search_documents(vector(384)) AS
SELECT id, content, 1 - (embedding <=> $1) AS cosine_similarity
FROM documents
ORDER BY embedding <=> $1
LIMIT 5;
-- EXECUTE search_documents('[0.0123, -0.0456, ...]');Límites y valores por defecto del README y el código fuente de pgvector 0.8.7, comprobados el 2026-11-04. README de pgvector
Todo se hace en tu navegador. La herramienta escribe SQL y no se conecta a nada.
pgvector es una extensión de código abierto que añade a PostgreSQL la búsqueda por similitud de vectores, de modo que los embeddings que creas con Ollama pueden guardarse en la misma base de datos que el resto de tus datos. Hay varios detalles fáciles de equivocar. La columna debe tener el mismo número de dimensiones que tu modelo de embeddings. Cada distancia tiene su propio operador: <=> para la distancia del coseno, <-> para la distancia L2, <#> para el producto interno negativo y <+> para la distancia L1. Un índice aproximado solo se usa si se creó con la clase de operador de la misma distancia, como vector_cosine_ops para <=>, y si la consulta ordena por el propio operador en orden ascendente con un LIMIT. Esta herramienta escribe las tres partes a partir de un único conjunto de opciones: CREATE EXTENSION y CREATE TABLE, CREATE INDEX, y una sentencia PREPARE que devuelve las filas más cercanas con una puntuación legible (la similitud del coseno es 1 menos la distancia del coseno, y el producto interno es <#> multiplicado por -1). Aplica los límites del README y del código fuente de pgvector para la versión 0.8.7: hasta 16,000 dimensiones en una columna, índices de hasta 2,000 dimensiones para vector y 4,000 para halfvec, sin clase de operador L1 para IVFFlat, m de HNSW de 2 a 100, y ef_construction de 4 a 1,000 y al menos 2 × m. Con HNSW, una búsqueda devuelve como máximo hnsw.ef_search filas (40 por defecto), así que la herramienta avisa cuando LIMIT es mayor. Para IVFFlat rellena lists y probes con los puntos de partida del README: rows / 1000 hasta 1M filas, sqrt(rows) por encima de eso, y sqrt(lists) para probes. El SQL generado se ejecutó en pgvector 0.8.7 con PostgreSQL 16 usando vectores reales de 384 dimensiones de Ollama, y EXPLAIN mostró que se usaba el índice.
La lógica principal de esta herramienta es de código abierto, con licencia MIT. github.com/seigo5555/toolkitbox-lib/src/pgvector-sql.ts
Casos de uso
- Crear la tabla para los fragmentos de tus documentos antes de cargar en PostgreSQL los embeddings de Ollama
- Comprobar qué operador va con qué clase de operador para la distancia del coseno, L2, producto interno o L1, para que el índice se use de verdad
- Estimar cuánto espacio ocupan los vectores en un VPS pequeño y comparar vector con halfvec
Cómo usarlo
- Escribe el nombre de la tabla y el número de dimensiones de tu modelo de embeddings. Es la longitud de un vector de /api/embed; el Embedding Similarity Calculator de este sitio la muestra.
- Elige el tipo, la distancia y el índice. La documentación de Ollama recomienda la similitud del coseno para la mayoría de las búsquedas semánticas, y /api/embed devuelve vectores de longitud 1.
- Copia los tres bloques y ejecútalos en psql u otro cliente. Crea un índice IVFFlat después de cargar los datos; un índice HNSW se puede crear en una tabla vacía.
FAQ
¿Qué distancia debo elegir?
La documentación de embeddings de Ollama recomienda la similitud del coseno para la mayoría de los casos de búsqueda semántica. En pgvector, <=> devuelve la distancia del coseno, y la herramienta la convierte en cosine_similarity con 1 menos la distancia. Para vectores de longitud 1, como los de /api/embed, la distancia del coseno, la distancia L2 y el producto interno ordenan las filas igual, porque para esos vectores la distancia L2 al cuadrado es 2 menos 2 veces la similitud del coseno.
¿HNSW o IVFFlat?
El README de pgvector dice que HNSW tiene mejor rendimiento de consulta que IVFFlat (en términos del equilibrio entre velocidad y exhaustividad), pero se construye más despacio y usa más memoria, y que se puede crear en una tabla vacía porque no tiene paso de entrenamiento. IVFFlat se construye más rápido, usa menos memoria y debe crearse cuando la tabla ya tiene algunos datos. Sin índice, pgvector hace una búsqueda exacta, que da una exhaustividad perfecta.
¿Por qué mi consulta no usa el índice?
El README dice que la consulta necesita ORDER BY y LIMIT, y que el ORDER BY debe ser el propio operador de distancia en orden ascendente, no una expresión como 1 - (embedding <=> …) DESC. El operador también debe coincidir con la clase de operador del índice: <=> con vector_cosine_ops, <-> con vector_l2_ops, <#> con vector_ip_ops y <+> con vector_l1_ops. La herramienta escribe ambos a partir de la misma elección. El README también señala que un escaneo de la tabla puede ser más rápido cuando la tabla es pequeña.
¿Por qué obtengo menos filas que LIMIT?
Con HNSW, los resultados están limitados por hnsw.ef_search, que es 40 por defecto; cuando probamos LIMIT 100 en una tabla de 200 filas, obtuvimos 40 filas hasta que subimos hnsw.ef_search a 100. El README añade que el filtrado con WHERE se aplica después de recorrer el índice, así que una condición puede dejar incluso menos filas. Desde la versión 0.8.0, los escaneos iterativos del índice (SET hnsw.iterative_scan = strict_order o relaxed_order) recorren más parte del índice cuando hace falta.
¿Qué es halfvec?
Un tipo de vector de media precisión. Cada vector ocupa 2 × dimensiones + 8 bytes en lugar de 4 × dimensiones + 8, y los índices HNSW e IVFFlat sobre halfvec admiten hasta 4,000 dimensiones en lugar de 2,000. Cada elemento es un número de coma flotante de media precisión, así que los valores se guardan con menos precisión.
¿Mis datos se envían a algún sitio?
No. La herramienta solo escribe SQL en tu navegador y nunca se conecta a una base de datos.
Artículos relacionados
- Guarda y busca embeddings de Ollama en PostgreSQL con pgvectorGuarda embeddings de Ollama en PostgreSQL con pgvector, búscalos con HNSW o IVFFlat y pasa los resultados a /api/chat para que la respuesta cite sus fuentes.
- Embeddings con Ollama: lo básico para búsqueda y RAGCrea embeddings con el /api/embed de Ollama: los modelos y sus tamaños, truncate y dimensions, vectores de longitud unitaria y similitud del coseno, según la documentación oficial.