昨日書いたこれ……
SQL Server Management Studioから実行すると1~2秒で結果を返すストアドプロシージャが、なぜかASP.NETのWebアプリから実行すると4分~5分もかかるという問題。とりあえず速度差が無くなったので報告。
対応案
Stackoverflowやらほかのブログなどから、以下の対応が有効そうというところまで昨日調べました。
- ARITHABORTオプションをONにする(日本語名:算術アボート)
- ストアドプロシージャを毎回リコンパイルする設定を行う
- ストアドプロシージャの引数をすべてローカル変数に移して使う
ARITHABORTをONにする方策
残念ながら効果が見られませんでした。目的のストアドプロシージャを実行する前に、「SET ARITHABORT ON」というステートメントをExecuteNonQueryで流したのですが効果なし。
毎回リコンパイルする方策
これが効きました。SQLとして流す方法もあるようなのですが、今使っている環境のソース構成がそういう余分なステートメントを受け付けないつくりだったので、ストアドプロシージャの定義自体に下記のように「WITH RECOMPILE」を追記。
ALTER PROCEDURE [dbo].[TestProcedure] ( @USER_ID NVARCHAR(50) ) WITH RECOMPILE AS BEGIN ……
これが効果あり。4分かかっていたデータ取得が2秒弱で終わるようになりました。
なぜ?(要勉強)
なぜこれが効いたかについて、正直なところ厳密な説明をするための知識が足りていません。要勉強です。推測ですが…
- Webアプリの画面上での選択によって、同じストアドプロシージャが異なる引数で呼び出されるというつくりだった。
- 実行計画などに引数の組み合わせも含めて格納されているため、ある引数のパターンでは有効な計画が、別の引数の組み合わせでは速度低下につながる、というような事象が起きていた。
なのかな、と。実際、下記のサイトでそういう記述がありました。
https://msdn.microsoft.com/en-us/library/ms190439.aspxmsdn.microsoft.com
「Before You Begin / Recommendations」の3つ目、
If parameter values on the procedure are frequently atypical, forcing a recompile of the procedure and a new plan based on different parameter values can improve performance.
まさにこれですね。
SQL Server Tuning Scripts: Performance Optimization Secrets
- 作者: Robin Schumacher
- 出版社/メーカー: Rampant Techpress
- 発売日: 2014/05/27
- メディア: ペーパーバック
- この商品を含むブログを見る
インサイドMS SQL SERVER 2005クエリチューニング&最適化編 (マイクロソフト公式解説書)
- 作者: Kalen Delaney、Sunil Agarwal、Craig Freedman、Adam Machanic、Ron Talmage,熊澤幸生((株)CSK Winテクノロジ),(株)オーパス・ワン
- 出版社/メーカー: 日経BP社
- 発売日: 2008/06/26
- メディア: 単行本
- 購入: 2人 クリック: 17回
- この商品を含むブログ (4件) を見る