私は以下のクエリを持っています:
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
上記のクエリは3秒で完了します。
上記のクエリが値を返す場合、ストアドプロシージャを終了する必要があるため、次のように書き直しました。
If Exists(
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
)
Begin
Raiserror('Source missing',16,1)
Return
End
ただし、これには10分かかります。
上記のクエリを次のように書き換えることもできます。これも3秒以内に完了します。
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source
if @@rowcount >0
Begin
Raiserror('Source missing',16,1)
Return
End
上記の書き換えの問題は、上記のクエリがより大きなストアドプロシージャの一部であり、複数の結果セットを返すことです。C#では、各結果セットを反復処理して処理を行います。
上記では空の結果セットが返されるため、このアプローチを使用する場合は、C#を変更して再度展開する必要があります。
私の質問は
使用するだけ
IF EXISTS
で計画が変更されて時間がかかるのはなぜですか?
以下に詳細を示します。詳細が必要な場合はお知らせください。
- テーブルと統計スクリプトを作成して、私の計画と同じ計画を取得します
- 遅い実行計画
高速実行計画
注:両方のクエリは同じです(パラメーターを使用)、唯一の違いはEXISTS
(匿名化中にいくつかの間違いを犯した可能性があります)です。
テーブル作成スクリプトは次のとおりです。
http://pastebin.com/CgSHeqXc- 小さなテーブルの統計
http://pastebin.com/GUu9KfpS- 大きなテーブルの統計