これは私がこれまでの研究から学んだことです。
.NETは、ManagementStudioにログインしたときに取得するものとは異なる接続設定を送信します。 SQLプロファイラーとの接続をスニッフィングすると表示される内容は次のとおりです。
-- 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
設定が同じであることを確認するために、SQLServerにログインしたときに実行するすべてのクエリの上にこれらの設定を貼り付けています。
この場合、切断して再接続した後、各設定を個別に試しましたが、arithabortをオフからオンに変更すると、問題のクエリが90秒から1秒に短縮されたことがわかりました。
最も可能性の高い説明は、パラメータスニッフィングに関連しています。これは、SQLServerが最も効果的なクエリプランであると考えるものを選択するために使用する手法です。接続設定の1つを変更すると、クエリオプティマイザが別のプランを選択する可能性があります。この場合、明らかに悪いプランが選択されています。
しかし、私はこれを完全には確信していません。この設定を変更した後、実際のクエリプランを比較しようとしましたが、差分に変更が表示されていません。
場合によってはクエリの実行が遅くなる可能性のあるarithabort設定について他に何かありますか?
解決策は単純に見えました。ストアドプロシージャの先頭にsetarithabortを配置するだけです。ただし、これは逆の問題につながる可能性があります。クエリパラメータを変更すると、突然、「オン」よりも「オフ」の方が高速に実行されます。
とりあえず、プランが毎回再生成されることを確認するために、「recompileを使用して」プロシージャを実行しています。この特定のレポートは、再コンパイルに1秒かかる可能性があるため、問題ありません。これは、戻るのに1〜10秒かかるレポート(モンスターです)ではあまり目立ちません。
ただし、これは、はるかに頻繁に実行され、わずか数ミリ秒でできるだけ早く戻る必要がある他のクエリのオプションではありません。