PRODPlataforma BaaS soberana europeaAbrir panel →

IA nativa · 9 lectura mínima

Índice HNSW en Postgres: índice bien para búsqueda de vectores

Affane Daylami · Fondateur · 6 de abril de 2026

volver al blog

HNSW es el algoritmo de indexación que pgvector recomienda para la búsqueda de vectores de similitud en Postgres. Esta guía muestra cómo crear un índice HNSW correctamente ajustado. Tres opciones importan: el tipo de columna según el tamaño de sus incrustaciones, los parámetros m y ef_construction en la construcción, y ef_search en cada solicitud para arbitrar la recuperación y la latencia.

Este texto en inglés se generó automáticamente a partir del original en francés y aún no ha sido revisado.
Esta página fue traducida automáticamente. La versión en inglés es autorizada.

La búsqueda de vectores nativos de Aurabase (RAG, pgvector, incrustaciones) se basa en este mismo mecanismo de indexación, descrito en detalle en la página AI nativa en Postgres. Esta guía asume una tabla de Postgres con pgvector ya instalado, una columna de tipo vectory al menos unos pocos miles de filas. A continuación, un escaneo secuencial simple suele ser más rápido que un índice aproximado.

Lo esencial

  • HNSW no requiere ninguna fase de entrenamiento, a diferencia de IVFFlat: el índice se construye sobre inserciones, disponible en pgvector desde la versión 0.5.0.
  • Dos parámetros establecen la calidad del índice en la construcción: m (conexiones por nodo, predeterminado 16) y ef_construction (ancho de búsqueda en la construcción, predeterminado 64).
  • Un tercer parámetro, hnsw.ef_search (valor predeterminado de pgvector: 40), se ajusta para cada solicitud, sin reconstruir el índice, para arbitrar la recuperación y la latencia.
  • pgvector limita la indexación HNSW de tipo vector a 2000 dimensiones. Más allá de eso (una incrustación con 3072 dimensiones, por ejemplo), es necesaria una conversión a halfvec para indexar.
  • pgvector 0.8.6 es la versión integrada en la imagen del inquilino de Aurabase Postgres, verificada directamente en Dockerfile el 24 de agosto de 2026.
#
entender

¿Qué es un índice HNSW en pgvector?

HNSW significa Mundo pequeño navegable jerárquico. Es un índice gráfico: cada vector se convierte en un nodo conectado con sus vecinos más cercanos, organizados en varias capas superpuestas. Una búsqueda comienza en la parte superior del gráfico, en la capa más dispersa, y luego desciende capa por capa hasta los vecinos más relevantes. El tiempo de búsqueda se vuelve así casi logarítmico, no lineal respecto del número de líneas.

IVFFlat, el otro índice de pgvector, funciona de manera diferente: divide el espacio vectorial en listas determinadas por un pase de entrenamiento en una muestra existente, antes de poder indexar nada. HNSW no tiene esta restricción, cada inserción enriquece directamente el gráfico, lo que simplifica el funcionamiento en una tabla que crece continuamente. Por otro lado, un índice HNSW consume más memoria y tarda más tiempo en construirse que un IVFFlat equivalente en el mismo volumen.

pgvector presenta soporte HNSW en la versión 0.5.0. Las versiones posteriores agregan capacidades útiles para esta guía: el tipo halfvec (0.7.0) para indexar más allá de 2000 dimensiones y el parámetro hnsw.iterative_scan (0.8.0) para mejorar la recuperación en consultas filtradas. Si compara pgvector con una base vectorial dedicada antes de decidir, nuestra comparación pgvector vs Pinecone, Weaviate y Qdrant detalla las compensaciones.

#
Paso 1

Verifique su versión de pgvector antes de crear el índice

Confirme primero la versión de pgvector instalada. Una extensión demasiado antigua hace que algunas funciones de esta guía fallen silenciosamente, en particular halfvec y hnsw.iterative_scan.

psqlsql
SELECT extversion FROM pg_extension WHERE extname = 'vector';

HNSW existe desde pgvector 0.5.0. El tipo halfvec, necesario para indexar incrustaciones más allá de 2000 dimensiones, requiere al menos la versión 0.7.0. El parámetro hnsw.iterative_scan solicita la versión 0.8.0.

En los proyectos de Aurabase, la pregunta no surge: la imagen de Postgres incorpora pgvector 0.8.6, tanto en el clúster de Postgres compartido (docker/Postgres.Dockerfile, construido directamente en pgvector/pgvector:0.8.6-pg16-bookworm) como en las 16 instancias CNPG de Postgres dedicadas por proyecto (docker/Postgres.CNPG.Dockerfile, que hereda pgvector 0.8.6 del oficial Imagen CloudNativePG). Verificado en ambos Dockerfiles el 24 de agosto de 2026.

#
Paso 2

Elija el tipo correcto de columna según el tamaño de sus incrustaciones

El tipo de columna depende del tamaño de sus incrustaciones, no sólo del modelo que las genera. pgvector almacena un vector clásico del tipo vector, con un límite de 16.000 dimensiones en almacenamiento. Pero la indexación HNSW en este tipo está limitada a 2000 dimensiones: más allá de eso, CREATE INDEX falla.

Los modelos de incrustación comunes a menudo superan este umbral: text-embedding-3-large de OpenAI o gemini-embedding-2 de Google producen de forma nativa hasta 3072 dimensiones. Para indexar estos vectores con HNSW, convierta la columna a halfvec (precisión de almacenamiento reducida a la mitad), lo que lleva el límite de indexación mucho más allá de las 2000 dimensiones.

DimensionescolumnaHNSW en vectorRequiere fundición
768incrustación_768siNo
1536incrustación_1536siNo
3072incrustación_3072No (> 2000 atenuaciones)Sí, emitir::halfvec(3072)

El motor Aurabase RAG ilustra este compromiso en producción: tres clases de dimensiones admitidas (768, 1536, 3072), almacenadas en tres columnas distintas de la misma tabla embeddings. Las columnas 768 y 1536 están indexadas directamente en HNSW en el tipo vector. La columna 3072 está indexada mediante una conversión ::halfvec(3072), precisamente para eludir el límite de dimensión de 2000.

migration.sqlsql
CREATE INDEX idx_embeddings_vec_768 ON embeddings
  USING hnsw (embedding_768 vector_cosine_ops)
  WHERE embedding_768 IS NOT NULL;

CREATE INDEX idx_embeddings_vec_1536 ON embeddings
  USING hnsw (embedding_1536 vector_cosine_ops)
  WHERE embedding_1536 IS NOT NULL;

CREATE INDEX idx_embeddings_vec_3072 ON embeddings
  USING hnsw ((embedding_3072::halfvec(3072)) halfvec_cosine_ops)
  WHERE embedding_3072 IS NOT NULL;

Para obtener detalles sobre la ingesta (fragmentación, llamada al proveedor de incorporación, inserción), consulte el tutorial de canalización RAG en pgvector.

#
Paso 3

Crea el índice con los parámetros m y ef_construction

La sintaxis mínima es suficiente para un primer índice, con los valores predeterminados de pgvector.

psqlsql
CREATE INDEX ON items
  USING hnsw (embedding vector_cosine_ops);

pgvector luego aplica m = 16 y ef_construction = 64. Para ajustar estos valores explícitamente, use la cláusula WITH:

psqlsql
CREATE INDEX ON items
  USING hnsw (embedding vector_cosine_ops)
  WITH (m = 24, ef_construction = 100);
Acelerar una construcción importante

Antes de crear un índice HNSW en una tabla grande, aumente temporalmente maintenance_work_mem para la sesión: esta es, según la propia documentación de pgvector, la palanca más directa para reducir el tiempo de construcción.

¿Qué cambia el parámetro m?

m establece el número máximo de conexiones que cada nodo del gráfico mantiene por capa. Un valor más alto densifica el gráfico: la recuperación aumenta, pero la memoria consumida y el tiempo de construcción también aumentan, aproximadamente de forma lineal. El valor predeterminado (16) es adecuado para la mayoría de los casos. Subir a 24 o 32 está especialmente justificado en incrustaciones grandes, donde la distinción entre vecinos cercanos y lejanos se vuelve más fina.

¿Qué cambia ef_construction?

ef_construction establece el tamaño de la lista de candidatos explorada durante la construcción del índice, para cada nodo insertado. Un valor más alto mejora la calidad del gráfico final y, por tanto, la posible retirada, a costa de un mayor tiempo de construcción. A diferencia de m, este parámetro no tiene costo en el momento de la consulta: es una inversión única, que se paga solo una vez cuando se crea el índice.

Índices parciales para varias clases de dimensiones en la misma tabla

Cuando una tabla almacena múltiples columnas vectoriales (una por clase de dimensión, como lo hace Aurabase), indexe cada columna por separado con una cláusula WHERE colonne IS NOT NULL. Este índice parcial evita indexar líneas vacías para clases no utilizadas por una línea determinada, lo que reduce el tamaño del índice y acelera su construcción sin costar nada en recuperación.

La elección de la clase de operador (vector_cosine_ops, vector_l2_ops o vector_ip_ops) debe corresponder a la métrica con la que se entrenó el modelo de incrustación. Los modelos de incrustación de texto más recientes están entrenados para la similitud del coseno: vector_cosine_ops (o halfvec_cosine_ops en una columna de conversión) es, por lo tanto, la opción predeterminada más segura.

#
Paso 4

Establecer ef_search en el momento de la consulta

ef_search se establece en cada consulta, no cuando se crea el índice. Establece el tamaño de la lista de candidatos explorados durante la búsqueda: cuanto mayor sea, mejor será el recuerdo, a costa de una mayor latencia. pgvector establece su valor predeterminado en 40.

psqlsql
SET LOCAL hnsw.ef_search = 100;

SELECT id, content
FROM embeddings
ORDER BY embedding <=> '[...]'::vector
LIMIT 10;

40 rara vez es suficiente cuando una consulta combina la búsqueda vectorial con un filtro WHERE aplicado después de escanear el índice (en un espacio de nombres, un inquilino o cualquier otro criterio de metadatos). El escaneo HNSW devuelve ef_search candidatos sin procesar, luego el filtro descarta parte de ellos. Si sobreviven muy pocos candidatos, el LIMIT final terminará sin cubrirse.

Por lo tanto, el motor Aurabase RAG expande ef_search dinámicamente según el top_ksolicitado, en lugar de mantener el valor fijo de 40: ef = max(top_k × 4, 64). Una búsqueda de los 5 resultados más cercanos utiliza ef_search = 64; una búsqueda de los 50 principales utiliza ef_search = 200. Esta fórmula sigue siendo ajustable según la variable de entorno para implementaciones que necesitan otra compensación entre recuperación y latencia.

pgvector 0.8 agrega una segunda palanca para este mismo problema: hnsw.iterative_scan. En el modo strict_order o relaxed_order, la búsqueda amplía gradualmente su búsqueda hasta que reúne suficientes resultados después del filtrado, en lugar de detenerse en una lista fija de candidatos. Aurabase lo activa por defecto en strict_order, pero protege la llamada en un punto de guardado. En una versión de pgvector anterior a la 0.8, donde este parámetro no existe, la consulta continúa en modo degradado en lugar de fallar.

#
ir más lejos

Construya el oleoducto RAG completo

Este índice HNSW es solo una parte del proceso completo de RAG: fragmentación, generación de incrustación, ingesta y luego búsqueda. Nuestro tutorial paso a paso construye esta canalización de un extremo a otro en pgvector, desde la primera inserción hasta la consulta de similitud. La documentación técnica también detalla todas las capacidades nativas de IA de Aurabase construidas en Postgres.

#
Preguntas frecuentes

Preguntas frecuentes

HNSW o IVFFlat: ¿cuál elegir con pgvector?+
HNSW es adecuado para la gran mayoría de casos de búsqueda de vectores en producción: mejor recuperación con igual latencia, sin fase de entrenamiento previa y buena tolerancia a tablas que crecen continuamente. IVFFlat sigue siendo relevante cuando la memoria disponible es muy limitada, a costa de una recuperación generalmente menor y un reentrenamiento necesario si la distribución de datos cambia significativamente.
¿Cuánta memoria planificar para un índice HNSW?+
El orden de magnitud depende directamente de m y del número de vectores indexados: cada nodo almacena hasta m conexiones por capa, además del propio vector. Para obtener una estimación confiable de su volumen real, cree el índice a partir de un subconjunto representativo de sus datos. Luego mida su tamaño con pg_relation_size() en lugar de confiar en una regla general no medida.
¿Podemos indexar incrustaciones de más de 2000 dimensiones con HNSW?+
No directamente en el tipo de vector: pgvector se niega a construir un índice HNSW más allá de 2000 dimensiones en este tipo. La solución es convertir la columna a halfvec en el momento de la creación del índice, lo que aumenta el límite de indexación al reducir a la mitad la precisión del almacenamiento. Este es exactamente el enfoque utilizado en la producción de la clase de incrustación de 3072 dimensiones de Aurabase.

¿LISTO PARA IMPLEMENTAR?

Tu backend en cinco minutos.

No se requiere tarjeta de crédito · 500 MB gratis · 50,000 MAU