Confronto delle prestazioni tra l'utilizzo della funzione Join e Window per ottenere valori di lead e lag


11

Ho una tabella con righe 20M, e ogni riga ha 3 colonne: time, ide value. Per ogni ide time, c'è un valueper lo stato. Voglio conoscere i valori di lead e lag di un determinato timeper uno specifico id.

Ho usato due metodi per raggiungere questo obiettivo. Un metodo utilizza join e un altro metodo utilizza le funzioni della finestra lead / lag con indice cluster attivo su timee id.

Ho confrontato le prestazioni di questi due metodi per tempo di esecuzione. Il metodo join richiede 16,3 secondi e il metodo della funzione finestra impiega 20 secondi, escluso il tempo necessario per creare l'indice. Questo mi ha sorpreso perché la funzione finestra sembra essere avanzata mentre i metodi di join sono forza bruta.

Ecco il codice per i due metodi:

Crea indice

create clustered index id_time
 on tab1 (id,time)

Metodo di partecipazione

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

Statistiche IO generate utilizzando SET STATISTICS TIME, IO ON:

Statistiche per il metodo Join

Ecco il piano di esecuzione per il metodo join

Metodo della funzione finestra

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

(Ordinare solo timerisparmiando 0,5 secondi.)

Ecco il piano di esecuzione per il metodo della funzione Window

Statistiche IO

[Statistiche per il metodo della funzione Finestra 4]


Ho controllato i dati sample_orig_month_1999e sembra che i dati grezzi siano ben ordinati da ide time. È questo il motivo della differenza di prestazioni?

Sembra che il metodo join abbia più letture logiche rispetto al metodo della funzione finestra, mentre il tempo di esecuzione per il primo è effettivamente inferiore. È perché il primo ha un parallelismo migliore?

Mi piace il metodo della funzione finestra a causa del codice conciso, c'è un modo per accelerarlo per questo problema specifico?

Sto usando SQL Server 2016 su Windows 10 a 64 bit.

Risposte:


11

Le prestazioni relativamente bassa fila in modalità di LEADe LAGfunzioni finestra confrontato con sé unisce non è una novità. Ad esempio, Michael Zilberstein ne ha scritto su SQLblog.com nel 2012. C'è un po 'di sovraccarico negli operatori del piano (ripetuto) Segmento, Progetto sequenza, Finestra spool e Stream Aggregate:

Sezione del piano

In SQL Server 2016 è disponibile una nuova opzione, che consente di abilitare l'elaborazione in modalità batch per gli aggregati di finestre. Ciò richiede una sorta di indice columnstore sulla tabella, anche se è vuoto. La presenza di un indice columnstore è attualmente richiesta affinché l'ottimizzatore consideri i piani in modalità batch. In particolare, abilita l'operatore in modalità batch di Window Aggregate molto più efficiente.

Per verificarlo nel tuo caso, crea un indice columnstore vuoto non cluster:

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

La domanda:

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;

Ora dovrebbe dare un piano di esecuzione come:

Piano di archiviazione righe in modalità batch

... che potrebbe benissimo essere eseguito molto più velocemente.

Potrebbe essere necessario utilizzare un OPTION (MAXDOP 1)suggerimento o altro per ottenere la stessa forma del piano quando si memorizzano i risultati in una nuova tabella. La versione parallela del piano richiede un ordinamento in modalità batch (o forse due), che potrebbe essere un po 'più lento. Dipende piuttosto dal tuo hardware.

Per ulteriori informazioni sull'operatore Aggregazione finestra modalità batch, consultare i seguenti articoli di Itzik Ben-Gan:

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.