A veces surge una tarea para "pegar" una selección integral con los mismos datos "en columnas" de los arreglos lineales pasados como parámetros en la consulta SQL.
¿Cómo se hace a veces?
WITH T1 AS ( SELECT row_number() OVER() rn , unnest v1 FROM unnest('{1,2,3,4}'::integer[]) ) , T2 AS ( SELECT row_number() OVER() rn , unnest v2 FROM unnest('{5,6}'::integer[]) ) SELECT T1.v1 , T2.v2 FROM T1 LEFT JOIN T2 USING(rn);
v1 | v2 ------- 1 | 5 2 | 6 3 | 4 |
Es decir, primero, cada una de las matrices se "expandió" en la muestra, se numeró, y luego este número se usó como la clave de conexión CTE ...
[mira explicar.tensor.ru]CON ORDINALIDAD
¡Más de una cuarta parte de todo el tiempo se gastó en un par de WindowAgg!
Pero si usamos una versión de PG no inferior a 9.4, podemos
usar WITH ORDINALITY para numerar los resultados de cualquier SRF, incluidos los no anómalos:
WITH T1 AS ( SELECT * FROM unnest('{1,2,3,4}'::integer[]) WITH ORDINALITY T(v1, rn) ) , T2 AS ( SELECT * FROM unnest('{5,6}'::integer[]) WITH ORDINALITY T(v2, rn) ) SELECT T1.v1 , T2.v2 FROM T1 LEFT JOIN T2 USING(rn);
[mira explicar.tensor.ru] .
Por lo tanto, nos deshicimos completamente del uso de las funciones de la ventana.
Multi-argumento UNNEST
Pero desde el punto de vista de la eficiencia, hasta ahora no todo es bueno: casi la mitad del tiempo fue a Hash Left Join.
Y el autor claramente procedió de la suposición de que la primera matriz es exactamente más larga, es por eso que usó LEFT JOIN. Pero esta suposición no siempre es correcta y puede causar problemas.
Para
evitarlo, usaremos
unnest para varias matrices al mismo tiempo , que apareció en la misma versión 9.4:
SELECT * FROM unnest( '{1,2,3,4}'::integer[] , '{5,6}'::integer[] ) T(v1, v2);
Como resultado, no quedó casi nada de la solicitud y del plan:
Function Scan on t (cost=0.01..1.00 rows=100 width=8) (actual time=0.006..0.007 rows=4 loops=1)
Por lo tanto, las posibilidades de cometer un error son mucho menores. Sí, y el tiempo de ejecución mejoró varias veces, y en matrices más largas el efecto será aún más notable.