Qué hay de nuevo en el planificador de consultas de Postgres 16

Las mejoras del planificador de consultas de PostgreSQL 16 están impulsando un nuevo escrutinio sobre cómo la base de datos elige y ejecuta planes de consulta, especialmente en torno a decisiones más arriesgadas como los nested loop joins y el impacto de estadísticas incompletas. Los participantes debaten el largo conflicto sobre añadir query hints o “congelar” planes como escotillas de escape cuando el optimizador elige planes patológicos, y exploran alternativas como mejores estadísticas, retroalimentación del planificador a partir de la ejecución y herramientas para visualizar y ajustar planes EXPLAIN. También señalan problemas prácticos —sobrecarga de compilación JIT, falta de caché compartida de planes y diferencias frente a sistemas como SQL Server— aunque en general coinciden en que PostgreSQL puede manejar cargas de trabajo grandes, pero todavía tiene margen para volverse más predecible y autocorrectivo.

Comparación entre query hints y el purismo del planificador

  • Gran debate recurrente: ¿debería Postgres admitir query hints?
  • Argumentos a favor de los hints:
    • Son críticos como una “escotilla de escape” cuando el planificador elige planes pésimos en producción.
    • Son útiles para mitigación rápida, validación de mejores planes y rendimiento consistente entre versiones.
    • Existe el deseo de hints fuera de banda (por queryid, stored outlines) e incluso capacidades de “congelar este plan”.
  • Argumentos en contra / preocupaciones:
    • Los hints pueden degradarse a medida que cambian los datos y las versiones, fijando planes malos.
    • Fomentan malas prácticas de DBA y perjudican la mantenibilidad.
    • La cultura de Postgres prefiere corregir el propio planificador y usar estadísticas más ricas en lugar de hints rígidos.
  • Ideas de compromiso: hints más suaves que influyan en las estimaciones de selectividad o en la tolerancia al riesgo en lugar de forzar tipos de join específicos.

Estadísticas, selectividad y riesgo del plan

  • Muchos planes lentos provienen de malas estimaciones de filas/selectividad (por ejemplo, asumir 1 fila, elegir nested loops y luego obtener muchas filas).
  • Discusión sobre estadísticas extendidas, correlaciones entre columnas y heurísticas actuales (multiplicar probabilidades independientes).
  • Deseo de:
    • Un planificador más “averso al riesgo” cuando las estimaciones son inciertas.
    • Capacidad para expresar conocimiento sobre la forma de los datos (series temporales monótonas, tamaño esperado de la tabla).
    • Retroalimentación del planificador a partir de la ejecución y posiblemente “aprendizaje” de planes malos con el tiempo.
    • Planificación de largo recorrido / multipaso para consultas OLAP pesadas.

Compilación JIT

  • Varios usuarios informan que JIT hace que las consultas sean drásticamente más lentas, especialmente consultas con muchos joins o con muchas particiones.
  • Las heurísticas para decidir cuándo habilitar JIT se consideran débiles; algunos desactivan JIT globalmente, especialmente para OLTP.
  • El código JIT actual no se cachea; se menciona trabajo para habilitar el caché y mejorar el modelado de costos.
  • Sentimiento general: las consultas paralelas ayudan de forma fiable; JIT es potente, pero arriesgado como valor predeterminado.

Inspección de planes y herramientas

  • Se valoran herramientas visuales como los visualizadores de explain (pev2, pgMustard, etc.).
  • Sin embargo, entender si un plan es “malo” y cómo arreglarlo sigue requiriendo un conocimiento profundo de joins, índices y estadísticas.
  • EXPLAIN ANALYZE se enfatiza como esencial; grandes discrepancias entre filas estimadas y reales son señales de alerta clave.

Postgres frente a otras bases de datos

  • Algunos afirman que MSSQL/Oracle tienen optimizadores, caché de planes, hints y un ecosistema circundante (trabajos, informes, mensajería) más maduros.
  • Otros señalan que Postgres escala bien en la práctica; las diferencias tienen más que ver con funciones y herramientas que con capacidad bruta.