Comparación de rendimiento entre el uso de la función Unir y Ventana para obtener valores de adelanto y retraso

11

Tengo una tabla con filas 20M, y cada fila tiene 3 columnas: time, id, y value. Para cada idy time, hay un valuepara el estado. Quiero saber los valores de adelanto y retraso de un determinado timepara 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 timey 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:

Estadísticas para el método de unión

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 timeahorra 0,5 segundos).

Aquí está el plan de ejecución para el método de función de Windows

Estadísticas IO

[Estadísticas para el método de función de ventana 4]


Verifiqué los datos sample_orig_month_1999y parece que los datos sin procesar están bien ordenados por idy 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.

Jason
fuente

Respuestas:

11

El rendimiento relativamente bajo del modo fila LEADy LAGlas funciones de ventana en comparación con las autouniones no es nada nuevo. Por ejemplo, Michael Zilberstein escribió sobre esto en SQLblog.com en 2012. Hay bastante sobrecarga en los operadores de plan Segmento (repetido), Proyecto de secuencia, Carrete de ventana y Agregado de flujo:

Sección del plan

En SQL Server 2016, tiene una nueva opción, que es habilitar el procesamiento en modo por lotes para los agregados de la ventana. Esto requiere algún tipo de índice de almacén de columnas en la tabla, incluso si está vacío. Actualmente se requiere la presencia de un índice de almacén de columnas para que el optimizador considere los planes de modo por lotes. En particular, habilita el operador de modo por lotes Window Aggregate mucho más eficiente.

Para probar esto en su caso, cree un índice de almacén de columnas no agrupado vacío:

 -- Empty CS index
CREATE NONCLUSTERED COLUMNSTORE INDEX dummy 
ON dbo.tab1 (id, [time], [value]) 
WHERE id < 0 AND id > 0;

La consulta:

SELECT
    T1.id,
    T1.[time],
    T1.[value],
    value_lag = 
        LAG(T1.[value]) OVER (
            PARTITION BY T1.id
            ORDER BY T1.[time]),
    value_lead =
        LEAD(T1.[value]) OVER (
            PARTITION BY T1.id
            ORDER BY T1.[time])
FROM dbo.tab1 AS T1;

Ahora debería dar un plan de ejecución como:

Plan de tienda de fila de modo de lote

... que bien puede ejecutarse mucho más rápido.

Es posible que necesite usar una OPTION (MAXDOP 1)u otra sugerencia para obtener la misma forma de plan al almacenar los resultados en una nueva tabla. La versión paralela del plan requiere una ordenación por lotes (o posiblemente dos), que bien puede ser un poco más lenta. Más bien depende de su hardware.

Para obtener más información sobre el operador Agregado de ventana de modo de lote, consulte los siguientes artículos de Itzik Ben-Gan:

Paul White 9
fuente