私は、次のようなKimberly TrippによるSQL Serverプランのキャッシュに関する優れた記事をいくつか読んでいます。 http://www.sqlskills.com/blogs/kimberly/plan-cache-and-optimizing-for-adhoc -workloads /
「アドホックワークロード用に最適化」するオプションさえあるのはなぜですか?これは常にオンになってはいけませんか?開発者がアドホックSQLを使用しているかどうかにかかわらず、それをサポートするすべてのインスタンス(SQL 2008+)でこのオプションを有効にせず、キャッシュの膨張を削減するのはなぜですか?
SQL Server開発チームは、最小の驚きの原則に取り組んでいます。そのため、SQL Serverは通常、以前のバージョンと同じように動作を維持するために新しい機能を無効にしています。
はい、アドホックワークロード用に最適化することで、計画キャッシュの膨張を減らすことができますが、常に最初にテストしてください。
[編集:カレンデラニーは、興味深い逸話で、これを有効にするのが適切ではない状況があるかどうかを、彼女のマイクロソフトエンジニアの友人の1人に尋ねたと言いました。彼は数日後に戻ってきて言っています-さまざまなクエリがたくさんあり、各クエリが合計で正確に2回実行されるアプリケーションを想像してください。それからそれは不適切かもしれません。そのようなアプリはそれほど多くないということで十分です!]
[編集:クエリの大部分が複数回実行されている場合(正確に2回ではない)。それはおそらく不適切です。一般的なルールは、データベースに1回限りのアドホッククエリが多数ある場合は有効にすることです。ただし、そのようなアプリはまだ多くありません。]
以下は、「アドホックワークロードの切り替え最適化ON/OFF」が有益かどうかを判断するのに役立つ小さなコードです。通常、社内サーバーとクライアントサーバーのヘルスチェックの一環としてこれをチェックします。
これは有効にする最も安全なオプションであり、Brad here およびGlenn Berry here によって適切に説明されています。
--- for 2008 and up .. Optimize ad-hoc for workload
IF EXISTS (
-- this is for 2008 and up
SELECT 1
FROM sys.configurations
WHERE NAME = 'optimize for ad hoc workloads'
)
BEGIN
DECLARE @AdHocSizeInMB DECIMAL(14, 2)
,@TotalSizeInMB DECIMAL(14, 2)
,@ObjType NVARCHAR(34)
SELECT @AdHocSizeInMB = SUM(CAST((
CASE
WHEN usecounts = 1
AND LOWER(objtype) = 'adhoc'
THEN size_in_bytes
ELSE 0
END
) AS DECIMAL(14, 2))) / 1048576
,@TotalSizeInMB = SUM(CAST(size_in_bytes AS DECIMAL(14, 2))) / 1048576
FROM sys.dm_exec_cached_plans
SELECT 'SQL Server Configuration' AS GROUP_TYPE
,' Total cache plan size (MB): ' + cast(@TotalSizeInMB AS VARCHAR(max)) + '. Current memory occupied by adhoc plans only used once (MB):' + cast(@AdHocSizeInMB AS VARCHAR(max)) + '. Percentage of total cache plan occupied by adhoc plans only used once :' + cast(CAST((@AdHocSizeInMB / @TotalSizeInMB) * 100 AS DECIMAL(14, 2)) AS VARCHAR(max)) + '%' + ' ' AS COMMENTS
,' ' + CASE
WHEN @AdHocSizeInMB > 200
OR ((@AdHocSizeInMB / @TotalSizeInMB) * 100) > 25 -- 200MB or > 25%
THEN 'Switch on Optimize for ad hoc workloads as it will make a significant difference. Ref: http://sqlserverperformance.idera.com/memory/optimize-ad-hoc-workloads-option-sql-server-2008/. http://www.sqlskills.com/blogs/kimberly/post/procedure-cache-and-optimizing-for-adhoc-workloads.aspx'
ELSE 'Setting Optimize for ad hoc workloads will make little difference !!'
END + ' ' AS RECOMMENDATIONS
END
5つの異なるクエリしか処理しないが、1秒あたり数千のクエリを提供する運用サーバーを考えてみてください。あなたはMicrosoft SQL Server開発チームです。プランのキャッシュをいじるつもりです。最大で最も重要なクライアント(Microsoftの内部SAP実装など)が同じキャンパスで動作し、同じカフェテリアを使用していることがわかっている場合、デフォルトでこの動作をオンにしますか?
「アドホックワークロード用に最適化」オプションをオンにすると、2回目に実行されるアドホッククエリが1回目と同じくらい遅くなります。最初の2回、実行プランをコンパイルし、同じデータを(キャッシュせずに)プルします。
これは大した問題ではないかもしれませんが、クエリをテストするときに気付くでしょう。
つまり、なしこのオプションがオンになり、キャッシュがいっぱいになります1回限りのアドホッククエリ?
この最適化機能が導入されたため、キャッシング管理アルゴリズムも更新されました。
Kimberly Trippの記事もこのアルゴリズムの変更について Kalen Delaneyの投稿 を参照しています。
彼女はそれを最もよく説明しています:
この変更により、実際にSQL Serverがメモリプレッシャーがあることを認識するプランキャッシュサイズが計算され、キャッシュからプランの削除が開始されます。削除される計画は、再利用されていない安価な計画であり、これは良いことです。
つまり、リソースを解放する必要がある場合は、厄介なワンタイムプランが最初に実行されます。
"SQL Serverが必要に応じて未使用のプランを削除する場合、なぜ「アドホックワークロードの最適化」が必要なのですか?"
これに対する私の答えは、パラメーター化されていないアドホッククエリの動的SQLを生成する大量のイベントが定期的にある場合、この機能をオンにすることは完全に理にかなっています。
最大キャッシュメモリ領域を使い果たした後、キャッシュされたプラン/データの削除を強制するなど、システムリソースに負担をかけないようにします。
これは、現在キャッシュしているアドホックプランの数と、それらが消費しているディスク領域の量を示すために私が書いたクエリです(結果は1日を通して変化するため、負荷が高いときにテストしてください)。
--Great query for making the argument to use "Optimize for Ad Hoc Workloads":
SELECT S.CacheType, S.Avg_Use, S.Avg_Multi_Use,
S.Total_Plan_3orMore_Use, S.Total_Plan_2_Use, S.Total_Plan_1_Use, S.Total_Plan,
CAST( (S.Total_Plan_1_Use * 1.0 / S.Total_Plan) as Decimal(18,2) )[Pct_Plan_1_Use],
S.Total_MB_1_Use, S.Total_MB,
CAST( (S.Total_MB_1_Use * 1.0 / S.Total_MB ) as Decimal(18,2) )[Pct_MB_1_Use]
FROM
(
SELECT CP.objtype[CacheType],
COUNT(*)[Total_Plan],
SUM(CASE WHEN CP.usecounts > 2 THEN 1 ELSE 0 END)[Total_Plan_3orMore_Use],
SUM(CASE WHEN CP.usecounts = 2 THEN 1 ELSE 0 END)[Total_Plan_2_Use],
SUM(CASE WHEN CP.usecounts = 1 THEN 1 ELSE 0 END)[Total_Plan_1_Use],
CAST((SUM(CP.size_in_bytes * 1.0) / 1024 / 1024) as Decimal(12,2) )[Total_MB],
CAST((SUM(CASE WHEN CP.usecounts = 1 THEN (CP.size_in_bytes * 1.0) ELSE 0 END)
/ 1024 / 1024) as Decimal(18,2) )[Total_MB_1_Use],
CAST(AVG(CP.usecounts * 1.0) as Decimal(12,2))[Avg_Use],
CAST(AVG(CASE WHEN CP.usecounts > 1 THEN (CP.usecounts * 1.0)
ELSE NULL END) as Decimal(12,2))[Avg_Multi_Use]
FROM sys.dm_exec_cached_plans as CP
GROUP BY CP.objtype
) AS S
ORDER BY S.CacheType
「X MBあるとき」または「アドホックのX%がシングルユース "の場合、これをオンにします。
Sprocs、トリガー、ビュー、パラメータ化/準備されたSQLには影響せず、アドホッククエリにのみ影響します。
私の個人的な推奨事項は、製品環境でオンにすることですが、開発環境ではオフにすることを検討してください。
私はこれをDevに対してonlyと言います。実行に1分以上かかるクエリを最適化している場合、実行したくないからです。キャッシュされた状態でどれほど高速になるかがわかる前に3回-every1回それを編集して、最適な最適化設計を見つけます。
あなたの仕事がこれを一日中行うことを含まない場合、気が狂って、あなたのDBAにどこでもそれをオンにするように頼んでください。
「なぜ使用しないのか...」パフォーマンスの調査中に、リソースの使用状況を確認しながら、プランキャッシュからプランをほぼリアルタイムで引き出すことが非常に役立ちます。 「アドホックワークロード用に最適化」は、キャッシュをクエリするときにアドホックスタブプランがプランを返さないため、それを混乱させる可能性があります。そのような場合、クエリとプランを他の方法で識別できない場合、調査のために設定のオンとオフを切り替えることができます。設定の変更は、それ以降にコンパイルされたクエリに影響することに注意してください。また、「サーバー」プロパティを変更するときは常に、同じバージョンの非製品インスタンスをチェックして、変更によってプランキャッシュがフラッシュされるかどうかを確認します。私は個人的にはそれに驚かれることを嫌います。 (たとえば、サーバーレベルでmaxdopを変更すると、通常プランキャッシュがフラッシュされますが、リソースガバナーでdopを変更するとフラッシュされません。)
「コンパイルされたプランスタブには実行プランが関連付けられておらず、プランハンドルをクエリしてもXMLプランは返されません。」 http://technet.Microsoft.com/en-us/library/cc645587.aspx