Ich habe eine Tabelle mit 20 M Zeilen und jede Zeile besteht aus 3 Säulen: time
, id
, und value
. Für jedes id
und time
gibt es ein value
für den Status. Ich möchte die Lead- und Lag-Werte eines bestimmten time
für einen bestimmten kennen id
.
Ich habe zwei Methoden angewendet, um dies zu erreichen. Eine Methode verwendet Join und eine andere Methode verwendet die Fensterfunktionen Lead / Lag mit Clustered Index auf time
und id
.
Ich habe die Leistung dieser beiden Methoden nach Ausführungszeit verglichen. Die Join-Methode dauert 16,3 Sekunden und die Fensterfunktionsmethode dauert 20 Sekunden, ohne die Zeit zum Erstellen des Index. Das hat mich überrascht, weil die Fensterfunktion erweitert zu sein scheint, während die Join-Methoden Brute Force sind.
Hier ist der Code für die beiden Methoden:
Index erstellen
create clustered index id_time
on tab1 (id,time)
Join-Methode
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
E / A-Statistiken generiert mit SET STATISTICS TIME, IO ON
:
Hier ist der Ausführungsplan für die Join-Methode
Fenster Funktionsmethode
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
(Bestellung nur mit time
spart 0,5 Sekunden.)
Hier ist der Ausführungsplan für die Fensterfunktionsmethode
E / A-Statistiken
[
Ich habe die Daten eingecheckt sample_orig_month_1999
und es scheint, dass die Rohdaten von id
und gut geordnet sind time
. Ist dies der Grund für Leistungsunterschiede?
Es scheint, dass die Join-Methode mehr logische Lesevorgänge aufweist als die Fensterfunktionsmethode, während die Ausführungszeit für die erstere tatsächlich kürzer ist. Liegt es daran, dass Ersteres eine bessere Parallelität hat?
Ich mag die Fensterfunktionsmethode wegen des prägnanten Codes. Gibt es eine Möglichkeit, sie für dieses spezielle Problem zu beschleunigen?
Ich verwende SQL Server 2016 unter Windows 10 64-Bit.