SQL Serverオプション「アドホックワークロード用に最適化」を使用しないのはなぜですか?


49

このようなKimberly TrippによるSQL Serverプランのキャッシュに関するいくつかの素晴らしい記事を読んでいます:http : //www.sqlskills.com/blogs/kimberly/plan-cache-and-optimizing-for-adhoc-workloads/

「アドホックワークロード向けに最適化する」オプションさえあるのはなぜですか?これは常にオンにすべきではありませんか?開発者がアドホックSQLを使用しているかどうかに関係なく、それをサポートするすべてのインスタンス(SQL 2008+)でこのオプションを有効にしないのはなぜですか?

回答:


45

SQL Server開発チームは最小限の驚きの原則に基づいて作業します。したがって、SQL Serverは通常、以前のバージョンと同様に動作を維持するために、新しい機能を無効にします。

はい、アドホックワークロード向けに最適化することは、プランキャッシュの肥大化を減らすのに優れていますが、常に最初にテストしてください!

[編集:Kalen Delaneyは、Microsoftのエンジニアの友人の1人に、これを有効にすることが適切でない状況があるかどうかを尋ねたという興味深い逸話を語ります。彼は数日後に戻って言います-さまざまなクエリがたくさんあり、各クエリが合計で正確に2回実行されるアプリケーションを想像してください。それは不適切かもしれません。そのようなアプリはそれほど多くないというだけで十分です!]

[編集:クエリの大部分が複数回(正確に2回ではなく)実行される場合。おそらく不適切でしょう。一般的なルールは、データベースに1回限りのアドホッククエリが多数ある場合に有効にすることです。ただし、そのようなアプリはまだ多くありません。]


9
+1新機能は、デフォルトでは非常にまれにしか有効になりません。この特定の機能をオンにしない理由は考えられません。最悪の場合、クエリはすべて使い捨てであり、いずれにしてもキャッシングの恩恵を受けられません。
アーロンバートランド

1
これは常識に基づいた「安全な」回答であり、質問には対応していません。質問者は、この機能をオンにしない方がよい場合のユースケースを具体的に知りたいと考えています。
MikeTeeVee

2
MikeTeeVee-それは安全な答えかもしれませんが、これは私が本当にそれを有効にしない理由を考えることができない機能の1つです。それはとても素晴らしいので、デフォルトでオフになった理由を説明したかっただけです!
ピータースコフィールド

21

以下は、「アドホックワークロードの最適化を ON / OFFに切り替える」ことが有益かどうかを判断するのに役立つ小さなコードです。通常、社内およびクライアントサーバーのヘルスチェックの一部としてこれをチェックします。

有効にするには最も安全な選択肢であるとブラッドにより十分に説明され、ここでグレン・ベリーによってここに

--- 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

7

5つの異なるクエリのみを処理する実稼働サーバーを考えてみましょう。ただし、1秒あたり数千のクエリを処理します。あなたはMicrosoft SQL Server開発チームです。プランのキャッシュをいじります。最大で最も重要なクライアント(Microsoftの内部SAP実装など)の一部が同じキャンパスで動作し、同じカフェテリアを使用していることがわかっている場合、デフォルトでこの動作をオンにしますか?


コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
ポールホワイト

7

アドホックワークロード向けに最適化」オプションをオンにすると、2回目に実行されるアドホッククエリが1回目と同じくらい遅くなります。これは、実行プランをコンパイルして同じデータ(キャッシュせずに)最初の2回。
これは大した問題ではないかもしれませんが、クエリをテストするときに気づくでしょう。
では、このオプションをオンにし、キャッシュに1回限りのアドホッククエリをいっぱいにしないと、どうなりますか?

キャッシング管理アルゴリズム:

この最適化機能が導入されたため、キャッシュ管理アルゴリズムも更新されました。
Kimberly Trippの記事は、このアルゴリズムの変更に関するKalen Delaneyの投稿も参照しています。
彼女はそれを最もよく説明しています:

この変更により、実際にプランのキャッシュサイズが計算されます。このサイズで、SQL Serverはメモリの負荷があることを認識し、キャッシュからプランの削除を開始します。削除される計画は、再利用されていない安価な計画であり、これは良いことです。

これは、リソースを解放する必要があるときに、これらの厄介なワンタイマー計画が最初に実行されることを意味します。

だから今の質問は次のようになります:

    「SQL Serverが必要なときに、未使用の計画を削除するの世話をするとき?なぜ我々は『アドホックワークロードの最適化』を必要なのですか

と私の答えはあなたが定期的に非パラメータ化広告の動的SQL生成どっさりのS-トンを持っている場合、 -hocクエリの場合、この機能をオンにするのが最適です。
最大キャッシュメモリ領域を使い果たした後、キャッシュプラン/データの削除を強制するように、システムリソースに負担をかけないようにします。

これをいつオンにする必要があるかを知るにはどうすればよいですか?

現在キャッシュしているアドホックプランの数と、それらが消費しているディスク領域の量を示すために私が書いたクエリは次のとおりです(結果は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%がシングルユースの場合」と言ってこれをオンにするつもりはありません。
Sproc、トリガー、ビュー、またはパラメーター化/準備されたSQLには影響せず、アドホッククエリにのみ影響します。
個人的な推奨事項は、Prod環境で有効にするだけですが、開発環境では無効にすることを検討してください。
私はこれを言うだけで、あなたが分以上実行にかかり、クエリを最適化している場合、その後、あなたはそれがキャッシュされたとして行くだろうどれだけ速く見ることができる前に、それを3回実行したくないので、デベロッパーのため- すべての一度だけ編集して、最適な最適化設計を見つけます。
あなたの仕事がこれを終日行うことを必要としない場合、気をつけて、DBAにどこでもそれをつけるように頼んでください。


0

「使用しない理由...」いくつかのパフォーマンス調査の過程で、リソースの使用率を観察しながら、プランキャッシュからプランをほぼリアルタイムで引き出すことが非常に役立ちます。「アドホックワークロード用に最適化」すると、アドホックスタブプランがキャッシュのクエリ時にプランを返さないため、混乱が生じる可能性があります。そのような場合、クエリとプランを特定できない場合、調査のために設定をオフとオンに切り替えることができます。設定の変更は、その時点からコンパイルされたクエリに影響することに注意してください。また、「サーバー」プロパティを変更するときは常に、同じバージョンのnonprodインスタンスをチェックして、変更によってプランキャッシュがフラッシュされるかどうかを確認してください。私は個人的にそのことに驚かれるのが嫌いです。(たとえば、サーバーレベルでmaxdopを変更すると、通常、プランキャッシュがフラッシュされ、

「コンパイルされたプランスタブには実行プランが関連付けられておらず、プランハンドルのクエリはXMLプラン表示を返しません。」 http://technet.microsoft.com/en-us/library/cc645587.aspx

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.