大規模な select ステートメントがあり、インデックス スキャンに 83% の時間がかかり、70 万行あると戻るのに何秒もかかります。ここでそのサブセットを作成しました:
set nocount on
create table #scanme ( lookid int identity primary key , stateid tinyint )
create nonclustered index scanstateid on #scanme (stateid) where stateid in ( 0 )
go
insert into #scanme values ( 0 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 0 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 0 )
go
insert into #scanme values ( 0 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 0 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 0 )
go
insert into #scanme values ( 0 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 0 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 0 )
go
insert into #scanme values ( 0 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 0 ) ; insert into #scanme values ( 1 ) ; insert into #scanme values ( 2 ) ; insert into #scanme values ( 0 )
go
select
sum( case when stateid=0 then 1 else 0 end ) as notdone
, sum( case when stateid=1 then 1 else 0 end ) as doneok
, sum( case when stateid=2 then 1 else 0 end ) as doneerrors
from
#scanme
今 SSMS でこれを実行すると、私が得ているのと同じ計画は表示されません。上記の DML は、私の問題がどこにあるかを示すためのものです。700k 行の場合、MSSQL がすべての stateid を調べて合計するため、合計要件によってインデックス スキャンが発生しているようです。
このクエリをすばやく返すようにする別のインデックス (または選択を変更する方法) を推奨できる人はいますか?
ありがとう。