私は20Mの行のテーブルを有し、各行は3つの列を有している:time
、id
、およびvalue
。それぞれについてid
とtime
、そこにあるvalue
状態のため。time
特定の特定の特定のリードとラグの値を知りたいid
。
これを達成するために2つの方法を使用しました。1つの方法は結合を使用し、もう1つの方法は、クラスター化インデックスがオンtime
およびのウィンドウ関数lead / lagを使用することid
です。
これら2つの方法のパフォーマンスを実行時間で比較しました。結合メソッドは16.3秒かかり、ウィンドウ関数メソッドは20秒かかります(インデックスの作成時間は含まれません)。結合メソッドがブルートフォースであるときにウィンドウ関数が進んでいるように見えるので、これは私を驚かせました。
2つのメソッドのコードは次のとおりです。
インデックスを作成
create clustered index id_time
on tab1 (id,time)
結合方法
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統計SET STATISTICS TIME, IO ON
:
これがjoinメソッドの実行計画です
ウィンドウ関数法
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
(time
0.5秒節約するだけで注文できます。)
ウィンドウ関数メソッドの実行計画はこちら
IO統計
[
私は、内のデータをチェックしsample_orig_month_1999
、生のデータが十分で注文しているようだid
とtime
。これがパフォーマンスの違いの理由ですか?
結合メソッドはウィンドウ関数メソッドよりも論理的な読み取りが多いようですが、前者の実行時間は実際には短くなっています。前者の方が並列処理が優れているからですか?
簡潔なコードのため、ウィンドウ関数メソッドが好きですが、この特定の問題に対してスピードを上げる方法はありますか?
Windows 10 64ビットでSQL Server 2016を使用しています。