La búsqueda vectorial en PostgreSQL ha avanzado mucho y pgvector facilita tareas básicas: insertar embeddings, crear un índice HNSW y ejecutar consultas ANN. Sin embargo, al escalar nuestro sistema por tiendas, regiones y volúmenes de producto en Q2BSTUDIO descubrimos que HNSW no es una solución de instalar y olvidar. Los índices envejecen, aumentan de tamaño, se fragmentan y pueden perder recall de forma silenciosa, degradando la calidad de búsqueda de forma gradual o incluso catastrófica.
Al principio adoptamos reconstrucciones programadas: reconstruir cada noche a la 1 AM, después de importaciones, tras nuevos embeddings, en resumen reconstruir siempre. Parecía seguro pero no lo fue. Reconstrucciones periódicas provocaron desperdicio masivo de CPU e IO cuando no había escrituras nuevas, pérdida diaria de recall en inquilinos grandes, aumento de latencias y casos en que una caída durante una reconstrucción concurrente dejó índices en estado INVALID que PostgreSQL seguía viendo pero no usando, rompiendo resultados por región y por réplica.
La lección fue clara: no necesitamos reconstrucciones ciegas y programadas, necesitamos monitoreo de salud del índice y reconstruir solo cuando sea necesario. ¿Qué significa saludable para un índice HNSW? A diferencia de los btrees con su porcentaje de bloat, HNSW es un grafo navegable multinivel cuya salud depende de cuántos vectores fueron reemplazados sin podado, cuántos nodos referencian embeddings inexistentes, si las capas siguen siendo navegables bajo presión de memoria y si el índice cabe en caché o empieza a paginar a disco. No existe una única métrica de fragmentación, así que diseñamos una basada en tres señales clave.
Modelo de salud basado en tres métricas: generamos una puntuación por índice combinando estas señales
1. Ratio de tuplas muertas
Detecta vectores eliminados o sobrescritos que siguen referenciados dentro del grafo, aumentan saltos y reducen recall.
Consulta de ejemplo
SELECT relname AS table_name , n_dead_tup , n_live_tup , ROUND (( n_dead_tup / GREATEST ( n_live_tup , 1 ):: float ) * 100 , 2 ) AS dead_tuple_ratio_pct FROM pg_stat_all_tables WHERE relname = your_embedding_table_name ;
Regla práctica
Si el ratio de tuplas muertas está entre 10 y 15 por ciento o más, merece la pena reconstruir.
2. Ratio de acierto en caché
Muchos problemas de rendimiento no vienen de la estructura sino de la expulsión de caché. Si las páginas HNSW salen de shared_buffers la navegación pasa a ser limitada por disco y el planner puede dejar de usar el índice.
Consulta de ejemplo
SELECT indexrelid :: regclass AS index_name , idx_blks_hit , idx_blks_read , ROUND (( idx_blks_hit * 100.0 / GREATEST ( idx_blks_hit + idx_blks_read , 1 )), 2 ) AS cache_hit_ratio_pct FROM pg_statio_user_indexes WHERE indexrelid :: regclass :: text LIKE %hnsw% ;
Interpretación
Ratio mayor de 90 por ciento indica salud, entre 90 y 75 por ciento alerta amarilla, debajo de 75 por ciento riesgo de estar ligado a disco y riesgo para el planner.
3. Bytes por vector
Heurística para detectar bloat estructural: si los bytes almacenados por embedding crecen más de lo esperado, reconstruir compensa.
Consulta de ejemplo
WITH idx AS ( SELECT c.relname AS index_name , pg_relation_size(c.oid) AS index_bytes FROM pg_class c JOIN pg_index i ON i.indexrelid = c.oid WHERE c.relname LIKE %hnsw% ) SELECT index_name , pg_size_pretty(index_bytes) AS index_size , ( index_bytes / NULLIF (( SELECT reltuples FROM pg_class WHERE relname = your_embedding_table_name ), 0 ) ) AS bytes_per_vector FROM idx ;
Regla práctica
Si esperas alrededor de 5 KB por vector y observas por ejemplo 9.2 KB por vector, la reconstrucción suele mejorar recall.
Combinamos las tres métricas en una puntuación de salud en lugar de una decisión binaria reconstruir o no. Fórmula sencilla
score = ( dead_score * 0.4 ) + ( cache_score * 0.4 ) + ( bloat_score * 0.2 )
Razonamiento de ponderación
Las tuplas muertas impactan directamente el recall y por eso tienen mayor peso. La residencia en caché afecta latencia y la fiabilidad del planner. El bloat importa pero su impacto relativo tiende a ser menor en embeddings grandes.
Si la puntuación cae por debajo de un umbral definido, se reconstruye solo ese índice.
Resultados: dejamos de reconstruir todo por defecto y solo reconstruimos cuando las señales lo justifican. El proceso es más inteligente, más rápido y más barato, y la calidad de búsqueda dejó de dar sorpresas desagradables.
En Q2BSTUDIO aplicamos este enfoque como parte de una oferta integral de servicios: desarrollamos Desarrollo de aplicaciones a medida y soluciones de software a medida que integran buenas prácticas de observabilidad de índices, y ofrecemos servicios de inteligencia artificial para empresas que requieren modelos semánticos, agentes IA y mejoras en recall y latencia. También cubrimos ciberseguridad y pentesting, servicios cloud AWS y Azure, servicios de inteligencia de negocio y Power BI, automatización de procesos y todo lo necesario para llevar soluciones escalables y seguras a producción.
Si gestionas índices HNSW con pgvector te recomendamos instrumentar estas métricas, definir umbrales basados en tu carga y automatizar la reparación selectiva. Con un monitoreo impulsado por señales evitarás reconstrucciones innecesarias, reducirás costes y mantendrás la experiencia de búsqueda consistente para tus usuarios.
Palabras clave: aplicaciones a medida, software a medida, inteligencia artificial, ciberseguridad, servicios cloud aws y azure, servicios inteligencia de negocio, ia para empresas, agentes IA, power bi.

.jpg)
.jpg)
