Índices IVFFlat vs HNSW
pgvector ofrece IVFFlat (archivo invertido con cuantización gruesa) y HNSW (mundo pequeño navegable jerárquico) para la búsqueda aproximada del vecino más cercano. Elija según los objetivos de recuperación, el presupuesto de RAM y la tolerancia al tiempo de construcción.
Receta
-- IVFFlat: agrupa listas, sondea en tiempo de consulta
CREATE INDEX ON documents
USING ivfflat (embedding extensions.vector_cosine_ops)
WITH (lists = 100);
SET ivfflat.probes = 10;
-- HNSW: índice de grafo (pgvector 0.5+, opción predeterminada para muchas cargas de trabajo)
CREATE INDEX ON documents
USING hnsw (embedding extensions.vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
SET hnsw.ef_search = 40;Cuándo recurrir a esto: La tabla supera ~50k vectores y ORDER BY distance LIMIT k exacto no cumple con el SLO de latencia.
Ejemplo de trabajo
-- Evaluar recuperación vs latencia (ejecutar en staging con conjunto de consultas etiquetado)
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, embedding <=> $1 AS dist
FROM documents
ORDER BY embedding <=> $1
LIMIT 10;
-- Comparar escaneos de índice
DROP INDEX IF EXISTS documents_ivfflat_idx;
CREATE INDEX documents_ivfflat_idx ON documents
USING ivfflat (embedding extensions.vector_cosine_ops) WITH (lists = 200);
DROP INDEX IF EXISTS documents_hnsw_idx;
CREATE INDEX documents_hnsw_idx ON documents
USING hnsw (embedding extensions.vector_cosine_ops)
WITH (m = 16, ef_construction = 128);
-- Medir: latencia p50/p95, recall@10 vs fuerza bruta en consultas de muestraLo que esto demuestra:
- IVFFlat necesita ajustar
listsyivfflat.probesen tiempo de consulta - HNSW expone
m,ef_constructionen la construcción yhnsw.ef_searchen la consulta EXPLAIN ANALYZEconfirma el escaneo de índice frente al escaneo secuencial- La medición de recuperación requiere un estándar de oro de fuerza bruta en consultas reservadas
Análisis detallado
IVFFlat
Construcción: Agrupa k-means (lists centroides). Cada vector se asigna a la lista más cercana.
Consulta: Busca las probes listas más cercanas, luego la distancia exacta dentro de esas listas.
| Parámetro | Efecto |
|---|---|
lists | Más listas = celdas más pequeñas, índice más grande, construcción más lenta |
ivfflat.probes | Mayor = mejor recuperación, consultas más lentas |
Pros: Menor memoria que HNSW para algunas formas; maduro en versiones anteriores de pgvector.
Contras: La recuperación es sensible a la distribución de datos; necesita REINDEX después de grandes cambios de datos; las listas deben escalar con la regla general sqrt(filas).
-- heurística de lists para N filas: sqrt(N) a N/1000
-- 1M filas: lists entre 1000 y 10000 dependiendo de las pruebas de referenciaHNSW
Construcción: Grafo en capas que conecta vecinos.
| Parámetro | Efecto |
|---|---|
m | Máximo de aristas por nodo (16 común) |
ef_construction | Lista de candidatos en tiempo de construcción (mayor = mejor grafo, construcción más lenta) |
hnsw.ef_search | Lista de candidatos en tiempo de consulta (mayor = mejor recuperación, más lento) |
Pros: Buen valor predeterminado de recuperación/latencia para pgvector 0.8+; menos sensible al orden de inserción que IVFFlat.
Contras: Mayor RAM durante la construcción; índice más grande en disco; las interacciones de vacuum necesitan monitorización a escala.
Matriz de decisión
| Factor | Prefiera IVFFlat | Prefiera HNSW |
|---|---|---|
| Prioridad de recuperación | Moderada, ajustable con sondas | Alta de fábrica |
| RAM de construcción | Presupuesto más ajustado | Puede permitirse RAM |
| Inserciones constantes | Reconstruir lotes IVFFlat periódicamente | HNSW maneja mejor las inserciones |
| Versión de pgvector | Restricciones heredadas | Predeterminado de producción 0.8+ |
| SLO de latencia de consulta | Flexible | Estricto p95 |
Mantenimiento de índices
-- Después de la importación masiva de embeddings
REINDEX INDEX CONCURRENTLY documents_hnsw_idx;
ANALYZE documents;
-- Monitorizar índices inválidos
SELECT indexrelid::regclass FROM pg_index WHERE NOT indisvalid;Trampas
- IVFFlat antes de cargar los datos - La construcción de una tabla vacía produce centroides inútiles. Solución: Construya el índice después de la carga masiva o use
REINDEXdespués de que la importación se complete. - lists = 1 - Recuperación absurda. Solución: Comience con
sqrt(n)y varíe las sondas en el script de benchmark. - ef_search demasiado bajo - HNSW omite vecinos. Solución: Aumente
hnsw.ef_searchhasta que recall@k se estabilice en el conjunto de referencia. - Desajuste de Opclass - Sigue siendo el principal problema de pgvector. Solución:
vector_cosine_opscon<=>. - Fallo de construcción CONCURRENTLY - Se deja un HNSW inválido. Solución: Elimine el índice inválido; reduzca los picos de
maintenance_work_memo construya fuera de horas pico sin CONCURRENTLY en un clon vacío. - Comparar manzanas con naranjas - k diferente, métricas diferentes. Solución: k fijo=10, las mismas 100 consultas, el mismo operador de distancia para todas las ejecuciones.
Alternativas
| Alternativa | Usar cuándo | No usar cuándo |
|---|---|---|
| Escaneo exacto | < 10k filas | Corpus de millones de filas |
| HNSW particionado por inquilino | Multi-inquilino masivo | Inquilinos pequeños, sobrecarga de operaciones |
| Servicio ANN externo | PG demostrado falla a escala | Pipelines de recuperación con muchas uniones |
| IVFFlat ahora, HNSW después | Emergencia de memoria | Puede permitirse una reconstrucción |
Preguntas frecuentes
¿Recomendación predeterminada PG 18?
HNSW con m=16, ef_construction=64-128; ajuste ef_search según el objetivo de recuperación.¿Puedo tener ambos índices?
Solo uno debe ser utilizado por el planificador; elimine el no utilizado para ahorrar espacio.¿HNSW Halfvec?
Soportado en pgvector reciente; reduce el almacenamiento a la mitad cuando el modelo lo permite.¿Construcción de índice en paralelo?
Use max_parallel_maintenance_workers; la construcción de HNSW consume mucha CPU y RAM.¿Actualizaciones en caliente?
Las actualizaciones frecuentes de embeddings fragmentan el grafo; programe REINDEX si la recuperación se desvía.¿ANN filtrado?
Índices parciales por inquilino o predicado de metadatos; pgvector carece de pre-filtrado enriquecido en todas las versiones.¿Límites en la nube?
Algunas instancias administradas limitan maintenance_work_mem; afecta el éxito de la construcción.¿Sondas IVFFlat por sesión?
SET ivfflat.probes en la sesión del pool de conexiones o SET LOCAL en la transacción.¿Script de benchmark?
Exporte 100 embeddings de consulta; compare los 10 principales ids con fuerza bruta.¿Actualizar de 0.7 a 0.8?
Lea las notas de la versión; planifique REINDEX después de ALTER EXTENSION UPDATE.Relacionado
- Conceptos básicos de pgvector - operadores y tipos
- pgvector a escala - memoria y vacuum
- Esquema de almacenamiento RAG - diseño del esquema
- REINDEX CONCURRENTLY - reconstrucción en línea
- Mejores prácticas de pgvector - no confíe en los valores predeterminados
Versiones de Stack: 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.