WITH w AS NOT MATERIALIZED ( SELECT * FROM very_very_big_table ) SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref WHERE w2.key = 123;
Hoy, un commit ha caído en el repositorio PostgreSQL, que le permite controlar el comportamiento del procesamiento de subconsultas CTE, a saber: ahora puede indicar explícitamente si la subconsulta se materializará por separado o si se ejecutará como parte de una consulta grande.
Esto entrará en PostgreSQL 12 y esto es un gran problema. Veamos por qué
Los programadores adoran CTE porque puede mejorar significativamente la legibilidad del código. Bueno, de hecho, algunas consultas analíticas pueden funcionar con docenas de tablas y varios grupos y filtros. Para escribir todo esto en una gran consulta, garantizado para obtener algo ilegible. Por lo tanto, usando el operador WITH
, secuencialmente, en pequeñas subconsultas (que reciben un nombre legible por humanos) describimos la lógica del trabajo y luego producimos el resultado. Muy comodo
Más precisamente, sería muy conveniente si no fuera por una cosa: el PostgreSQL actual ejecuta estas subconsultas por separado, las materializa (escribe el resultado en una tabla temporal). Esto puede conducir a una desaceleración significativa en comparación con un gran monstruo ilegible. Especialmente si las subconsultas CTE devuelven millones de filas.
Sin embargo, hay situaciones en las que una ejecución tan separada funciona para el bien: existe un truco de optimización cuando es mejor ejecutar parte de una solicitud compleja por separado, pero el postgres no lo entiende por sí solo. Luego sacamos esta parte en la subconsulta CTE.
En general, las situaciones son diferentes, por lo que Postgres 12 realizó una confirmación agregando palabras clave MATERIALIZED
y NOT MATERIALIZED
, que indican si se debe materializar la consulta o en línea, respectivamente.
Además, el comportamiento predeterminado ha cambiado. Ahora la subconsulta CTE se alineará de manera predeterminada si su resultado se usa una vez. De lo contrario, se materializará como antes.