semillero-INVIMA/benchmarks/INFORME_OPTIMIZACION_BUSQUEDA.md

3.7 KiB

Informe de optimizacion de busqueda textual

Generado: 2026-07-12T23:05:19.481Z

1. Problema encontrado

Las consultas query_06 y query_07 evaluan la busqueda textual de marcapasos combinando busqueda FTS sobre search_text con condiciones ILIKE '%marcapasos%' sobre registro_sanitario, expediente, producto, categoria_canonica y categoria_linea. Antes de optimizar, PostgreSQL eligio Parallel Seq Scan, por lo que recorrio la tabla completa y aplico el filtro despues de leer cientos de miles de bloques.

2. Plan SQL anterior

  • query_06: Limit, Incremental Sort, Gather Merge, Index Scan; Seq Scan=0; bloques leidos=534.792; bloques hit=131.732; filas removidas=183.095; ejecucion=14.730,796 ms.
  • query_07: Aggregate, Bitmap Heap Scan, BitmapOr, Bitmap Index Scan; Seq Scan=0; bloques leidos=2.706; bloques hit=476; filas removidas=0; ejecucion=175,02 ms.

3. Cambios implementados

Se mantuvo intacta la semantica de las consultas. La migracion agrega indices GIN trigram de expresion sobre los mismos COALESCE(..., '') usados por los predicados ILIKE, elimina el indice de orden de benchmark si estaba invalido y aumenta estadisticas de columnas de busqueda. ANALYZE se dejo como accion manual porque en esta base local falla por bytes con codificacion invalida en datos existentes.

4. Indices nuevos

Indice Tamano Valido Listo
idx_bench_catalog_producto_coalesce_trgm 130 MB true true
idx_bench_catalog_registro_coalesce_trgm 42 MB true true
idx_bench_catalog_categoria_linea_coalesce_trgm 29 MB true true
idx_bench_catalog_categoria_canonica_coalesce_trgm 28 MB true true
idx_bench_catalog_expediente_coalesce_trgm 26 MB true true

5. Validacion funcional

  • Conteo antes: 430.
  • Conteo despues: 430.
  • Faltantes: 0.
  • Adicionales: 0.
  • Duplicados despues: 0.
  • Cambio de orden: false.
  • Cambio de claves ORDER BY: false.
  • Nota de orden: Sin observaciones
  • Resultado: VALIDO, sin diferencias funcionales.

6. Resultados antes y despues

  • query_06: promedio 56,6463 ms -> 17,6873 ms (mejora 38,959 ms, 68,7759 %); p95 62,8487 ms -> 18,4071 ms (mejora 44,4416 ms, 70,712 %).
  • query_07: promedio 55,0169 ms -> 35,5003 ms (mejora 19,5166 ms, 35,4738 %); p95 59,4553 ms -> 59,7619 ms (mejora -0,3066 ms, -0,5157 %).

7. Plan SQL posterior

  • query_06: Limit, Bitmap Heap Scan, BitmapOr, Bitmap Index Scan, Sort, CTE Scan; Seq Scan=0; Bitmap=8; bloques leidos=0; bloques hit=5.104; ejecucion=18,424 ms.
  • query_07: Aggregate, Bitmap Heap Scan, BitmapOr, Bitmap Index Scan; Seq Scan=0; Bitmap=8; bloques leidos=0; bloques hit=3.182; ejecucion=15,557 ms.

8. Criterios

  • query_06: Cumple objetivo textual. Objetivo: promedio <= 3 s, p95 <= 5 s, ideal < 1 s.
  • query_07: Cumple objetivo de conteo. Objetivo: promedio <= 5 s, p95 <= 8 s.

9. Riesgos e impacto

Los indices GIN adicionales consumen espacio y pueden aumentar el costo de futuras inserciones o actualizaciones en columnas textuales. No modifican datos regulatorios ni cambian resultados. El conteo exacto sigue evaluando todo el conjunto de coincidencias; si no cumple el objetivo, la siguiente alternativa es reescribir la busqueda como UNION/deduplicacion exacta o separar el conteo exacto como operacion diferida sin cambiar la ruta que lo obtiene.

10. Reversion y repeticion

Revertir:

npm.cmd run benchmark:rollback

Repetir pruebas:

$env:BENCHMARK_QUERY_IDS="query_06,query_07"
$env:BENCHMARK_REPETITIONS="100"
$env:BENCHMARK_WARMUPS="5"
npm.cmd run benchmark:optimized
node benchmarks/scripts/validate-search-results.js after
npm.cmd run benchmark:search:report

EA, MSE, precision y exhaustividad no calculables por ausencia de un conjunto de referencia validado.