Ho una tabella con righe 20M, e ogni riga ha 3 colonne: time
, id
e value
. Per ogni id
e time
, c'è un value
per lo stato. Voglio conoscere i valori di lead e lag di un determinato time
per 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 time
e 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
:
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 time
risparmiando 0,5 secondi.)
Ecco il piano di esecuzione per il metodo della funzione Window
Statistiche IO
[
Ho controllato i dati sample_orig_month_1999
e sembra che i dati grezzi siano ben ordinati da id
e 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.