Tengo una tabla con filas 20M, y cada fila tiene 3 columnas: time
, id
, y value
. Para cada id
y time
, hay un value
para el estado. Quiero saber los valores de adelanto y retraso de un determinado time
para un específico id
.
He usado dos métodos para lograr esto. Un método está usando join y otro método está usando las funciones de ventana lead / lag con índice agrupado en time
y id
.
Comparé el rendimiento de estos dos métodos por tiempo de ejecución. El método de unión tarda 16,3 segundos y el método de la función de ventana tarda 20 segundos, sin incluir el tiempo para crear el índice. Esto me sorprendió porque la función de ventana parece estar avanzada mientras que los métodos de unión son fuerza bruta.
Aquí está el código para los dos métodos:
Crear índice
create clustered index id_time
on tab1 (id,time)
Método de unión
select a1.id,a1.time
a1.value as value,
b1.value as value_lag,
c1.value as value_lead
into tab2
from tab1 a1
left join tab1 b1
on a1.id = b1.id
and a1.time-1= b1.time
left join tab1 c1
on a1.id = c1.id
and a1.time+1 = c1.time
IO estadísticas generadas usando SET STATISTICS TIME, IO ON
:
Aquí está el plan de ejecución para el método de unión
Método de función de ventana
select id, time, value,
lag(value,1) over(partition by id order by id,time) as value_lag,
lead(value,1) over(partition by id order by id,time) as value_lead
into tab2
from tab1
(Ordenar solo por time
ahorra 0,5 segundos).
Aquí está el plan de ejecución para el método de función de Windows
Estadísticas IO
[
Verifiqué los datos sample_orig_month_1999
y parece que los datos sin procesar están bien ordenados por id
y time
. ¿Es esta la razón de la diferencia de rendimiento?
Parece que el método de unión tiene más lecturas lógicas que el método de función de ventana, mientras que el tiempo de ejecución para el primero es en realidad menor. ¿Es porque el primero tiene un mejor paralelismo?
Me gusta el método de la función de ventana debido al código conciso, ¿hay alguna forma de acelerarlo para este problema específico?
Estoy usando SQL Server 2016 en Windows 10 de 64 bits.