これは、私がこれまでの研究から学んだことです。
.NET は、management studio にログインしたときに得られるものとは異なる接続設定を送信します。Sql Profiler で接続をスニッフィングすると、次のように表示されます。
-- network protocol: TCP/IP
set quoted_identifier off
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls off
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level read committed
設定が同じであることを確認するために、SQLサーバーにログインしたときに実行するすべてのクエリの上にこれらの設定を貼り付けています。
この場合、切断して再接続した後、各設定を個別に試してみたところ、arithabort をオフからオンに変更すると、問題のクエリが 90 秒から 1 秒に短縮されることがわかりました。
最も可能性の高い説明は、パラメータ スニッフィングに関連しています。これは、Sql Server が最も効果的なクエリ プランであると考えるものを選択するために使用する手法です。接続設定の 1 つを変更すると、クエリ オプティマイザーが別のプランを選択する可能性があります。この場合、明らかに不適切なプランが選択されます。
しかし、私はこれについて完全に確信しているわけではありません。この設定を変更した後、実際のクエリ プランを比較してみましたが、差分に変更が表示されていません。
場合によっては、クエリの実行が遅くなる可能性がある arithabort 設定について他に何かありますか?
解決策は簡単に思えました: set arithabort on をストアド プロシージャの先頭に置くだけです。しかし、これは逆の問題につながる可能性があります: クエリ パラメータを変更すると、突然、「オン」よりも「オフ」の方が速く実行されます。
とりあえず、計画が毎回再生成されるように、'with recompile' という手順を実行しています。この特定のレポートでは、再コンパイルにおそらく 1 秒かかるため問題ありません。これは、返されるのに 1 ~ 10 秒かかるレポート (モンスターです) ではあまり目立ちません。
しかし、これは、はるかに頻繁に実行され、わずか数ミリ秒でできるだけ早く返す必要がある他のクエリのオプションではありません。