Ben 20M satırları olan bir tablo ve her bir sırada 3 sütun var time
, id
ve value
. Her biri için id
ve time
bir orada value
statü için. Belli bir kişi time
için belirli bir kişinin kurşun ve gecikme değerlerini bilmek istiyorum id
.
Bunu başarmak için iki yöntem kullandım. Bir yöntem birleştirme yöntemini, bir diğer yöntem de time
ve id
.
Bu iki yöntemin performansını yürütme süresine göre karşılaştırdım. Join yöntemi 16.3 saniye sürer ve window işlevi yöntemi dizini oluşturma süresi dahil değil 20 saniye sürer. Bu beni şaşırttı çünkü birleştirme yöntemleri kaba kuvvetken pencere işlevi gelişmiş gibi görünüyor.
İki yöntemin kodu:
Dizin Oluştur
create clustered index id_time
on tab1 (id,time)
Birleştirme yöntemi
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 istatistikleri kullanılarak oluşturulmuştur SET STATISTICS TIME, IO ON
:
Join yöntemi için yürütme planı
Pencere İşlev yöntemi
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
(Sipariş sadece time
0,5 saniyedir.)
İşte Pencere işlev yöntemi için yürütme planı
ES istatistikleri
[
Verileri kontrol ettim ve sample_orig_month_1999
ham verilerin id
ve tarafından sipariş edildiği görülüyor time
. Performans farkının nedeni bu mu?
Join yönteminin pencere işlev yönteminden daha mantıklı okumalara sahip olduğu görülürken, birincisi için yürütme süresi aslında daha azdır. Birincisi daha iyi bir paralellik içerdiğinden mi?
Kısa kod nedeniyle pencere işlev yöntemini seviyorum, bu belirli sorun için hızlandırmak için herhangi bir yolu var mı?
SQL Server 2016'yı Windows 10 64 bit üzerinde kullanıyorum.