Webサイトを運用しているとアプリケーションを変更していないのに、タイムアウトを起こしたり、サイトレスポンスが遅くなる時があります。
一つのシナリオとして、データが更新されるなどして、今まで利用していた実行プランが無効となり、
再コンパイルされる際に不適切な実行プランが作られてしまう場合です。
実行プランが再コンパイルされる契機はこちら
https://technet.microsoft.com/ja-jp/library/ms181055(v=sql.105).aspx
実行プランの再コンパイル
パラメータを使用したクエリで、偏りのあるデータを検索する場合
少数派の条件で実行プランが作成されてしまった場合
多数派の条件をパラメータとした検索でレスポンスが悪化してしまうなど
→パラメータスニッフィング
実行プランの確認用
クエリが分かっている場合は、条件に入れてください。
検索結果のquery_planをクリックすると実行プランが確認できます。
-------------- --プラン XML SELECT TOP 10 [Average CPU used] = total_worker_time / qs.execution_count ,[Total CPU used] = total_worker_time ,[Execution count] = qs.execution_count ,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2, (CASE WHEN qs.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2 ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) ,[Parent Query] = qt.text ,DatabaseName = DB_NAME(qt.dbid) ,qp.query_plan FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt CROSS APPLY sys.dm_exec_query_plan (qs.plan_handle ) as qp --WHERE qt.text LIKE ('%クエリの検索用文字列%') ORDER BY [Average CPU used] DESC;
●同じ条件のクエリをManagement Studioで実行するとレスポンスが速い
Management Studioはデフォルトで、SET ARITHABORT ONが設定されています。
https://msdn.microsoft.com/ja-jp/library/ms190306.aspx
>ARITHABORT が OFF に設定されているクライアント アプリケーションは異なるクエリプランを受け取り、
>パフォーマンスに問題のあるクエリのトラブルシューティングが困難になる場合があります。
単純に比較できない。
●OPTION(RECOMPILE)を付ける
毎回、再コンパイルされます。
実行プランがキャッシュされず、毎回コンパイル時のCPUコストがかかります。
●ADHOCなクエリ、適当なコメントを付けて別のクエリと認識させる
パラメータ値のパターン分、多数の実行プランが作成されてしまい、
プロシージャキャッシュを食いつぶす可能性があります。
★OPTIMIZE FOR UNKNOWNを付ける
https://msdn.microsoft.com/ja-jp/library/ms181714.aspx
クエリ ヒント
>クエリ オプティマイザーでクエリをコンパイルおよび最適化するときに、
>強制パラメーター化によって作成されたパラメーターも含め、
>すべてのローカル変数に対して初期値の代わりに統計データを使用することを指定します。
●トレースフラグ 4136
OPTIMIZE FOR UNKNOWNヒントを付けるのと同様
設定がDB全体に掛かります。
--トレースフラグ4136設定 DBCC TRACEON(4136, -1) --すべてのプランキャッシュを削除 DBCC FREEPROCCACHE --確認 DBCC TRACESTATUS
--トレースフラグ4136削除 DBCC TRACEOFF(4136, -1) --すべてのプランキャッシュを削除 DBCC FREEPROCCACHE --確認 DBCC TRACESTATUS