sql >> データベース >  >> RDS >> Sqlserver

SQLServer2012でのquery_post_execution_showplan拡張イベントの影響

    SQL Serverで最も難しい課題の1つは、ワークロードのパフォーマンスの低下を引き起こすパラメーターの感度またはカーディナリティの見積もりに関する問題のトラブルシューティングです。通常、パフォーマンスの低下の原因を特定できるようにするには、実行中のステートメントから実際の実行プランを取得する必要があります。 SQL Server 2012では、query_post_execution_showplan拡張イベントは、ステートメントの実際の実行プランをキャプチャする機能を提供します。ただし、これは便利なようですが、このイベントは、サーバーで実行されているワークロードに大きなパフォーマンスの影響を与えることなく使用できるものではありません。

    私の記事「SQLトレースと拡張イベントの「オブザーバーオーバーヘッド」の測定」では、SQL Server 2012の拡張イベントを使用した同一の構成に対するSQLトレースのパフォーマンスへの影響の比較を示しました。当時、私はその記事のテストを行いました。また、SQL Server 2012でquery_post_execution_showplanイベントの多くのテストを行いました。このイベントは、SQLTraceとの同等性を提供するために多くのトレースイベントが拡張イベントに移植されたときにSQLServer2012CTP1で最初に導入されました。当時、イベントには、SQLServer2012の最終的なRTMに含まれていた列のサブセットしかありませんでした。

    CTP1中に、SQL Server 2012のイベントを含む実際の実行プランの収集を許可するアクションの作成を要求するConnectアイテムを送信しました。目標は、module_endイベントまたはsql_statement_completedイベントを使用して、プロシージャの実行時期を特定できるようにすることでした。またはステートメントが通常の期間を超えています。たとえば、パラメータ感度のシナリオでは、通常のパラメータ値に対してあまり理想的ではないプランが生成され、イベントを使用して、アクションを通じてそのステートメントの実際の実行プランを収集できます。これに応じて、SQL Serverチームはduration列とcpu_time列をquery_post_execution_showplanイベントに追加して、述語定義がこれらのシナリオでのみこのイベントを収集できるようにしました。

    残念ながら、これには、アクションとしての実装がパフォーマンスに与えるメリットと同じメリットはありません。この投稿の残りの部分では、その理由を説明します。

    パフォーマンスへの影響

    前回の記事のテストを行ったとき、query_post_execution_showplanイベントに関連するオーバーヘッドもテストしました。これは主に、いくつかのクライアント実稼働システムでの使用に非常に興味があり、その前に何を理解する必要があるかを理解する必要があったためです。イベントがワークロードに与える影響のようなものです。元のテストから得られた結果に本当にがっかりしました。AaronBertrandにSQLSentryの社内テストハーネスを使用して結果を検証させた後、パフォーマンスの問題を報告する別のConnectアイテムを提出しましたが、その後「設計による」としてクローズされました。 。

    パフォーマンスへの影響をテストするために、SQLトレースと拡張イベントの「オブザーバーオーバーヘッド」の測定に関する記事とまったく同じワークロードと分散リプレイ構成を使用しました。この記事に示されているテスト結果の唯一の違いは、VM環境に新しいより強力なホストシステムが使用されたことです。使用されたVMはまったく同じで、構成に変更はなく、新しいシステムにコピーされただけでした。そのため、ベースラインワークロードは、より高い平均バッチリクエスト/秒でより高速に再生を実行できました。ベースラインの結果は、サーバーで実行されているデフォルトのsystem_healthイベントセッションのみを使用して、標準のSQLServer2012インストールを使用してキャプチャされました。

    query_post_execution_showplanのパフォーマンスへの影響を比較するため イベントでは、次のイベントセッション定義が使用されました。

    CREATE EVENT SESSION [query_post_execution_showplan Overhead]
    ON SERVER
    ADD EVENT sqlserver.query_post_execution_showplan(
    WHERE ([duration]=(5000000)));
    GO

    このセッションは、ターゲットを使用して実際にイベントデータを収集するのではなく、イベント期間が5000000マイクロ秒または5秒の期間である期間の述語を使用します。リプレイワークロードの場合、実行中のステートメントの継続時間は正確に5秒ではないため、query_post_execution_showplanイベントがサーバーで実際に発生することはなく、パフォーマンスの低下は厳密にイベントデータ収集と述語評価の結果です。テストの結果を表1に示し、図2に示します。


    表1-query_post_executionイベントのオーバーヘッド


    グラフ2–query_post_executionイベントのオーバーヘッド

    このラウンドのテストでは、サーバーで再生されているどのイベントに対しても起動されない場合でも、イベントセッションでこのイベントを有効にするだけで、ワークロードのパフォーマンスが約30%低下します。全体的な劣化はサーバーの実際のワークロードによって異なります。分散再生がストレスモードで実行され、SQL ServerのCPU使用率が固定されているため、この一連のテストは最悪のシナリオを反映していることに注意してください。テスト中の平均は94%でした。

    パフォーマンスへの影響を理解する

    このイベントがパフォーマンスにこのような大きなオーバーヘッドを課す理由は、拡張イベントのイベントライフサイクルから説明できます。実行中にイベントに関連付けられたSQLServerコードの重要なポイントが検出されると、コードは非常に高速なブールチェックを実行して、サーバー上のアクティブなイベントセッションでイベントが有効になっているかどうかを判断します。イベントがアクティブなイベントセッションに対して有効になっている場合、オンになっているカスタマイズ可能な列を含め、イベントに関連付けられているすべてのデータ列が収集されます。この時点で、イベントは、イベントを収集しているアクティブなイベントセッションの述語を評価して、イベントが実際に完全に発生するかどうかを判断します。

    query_post_exection_showplanイベントの場合、パフォーマンスへの影響はすべて、データ収集に関連するオーバーヘッドによるものです。 5秒に等しい期間の述語がある場合でも、イベントセッションでイベントをオンにするだけで、述語を評価できるようにするために、サーバーで実行されるすべてのステートメントのShowplanXMLを収集する必要があります。次に、イベントが発生しないことを確認します。このため、実稼働ワークロードではquery_post_execution_showplanイベントを回避する必要があります。テストリプレイワークロードの場合、正確に5秒の期間のリプレイイベントはないため、テスト対象のワークロードとイベントセッションでは実際には発生しませんが、イベントは約440,000回評価する必要がありました。イベントカウント情報は、event_counterターゲットをイベントセッションに追加し、duration述語を削除してから、次のセッション定義を使用してリプレイワークロードを再テストすることによって収集されました。

    CREATE EVENT SESSION [query_post_execution_showplan Overhead] 
    ON SERVER
    ADD EVENT sqlserver.query_post_execution_showplan
    ADD TARGET package0.event_counter;
    GO

    急速に発火するイベントとの比較

    このパフォーマンスへの影響の参照フレームを提供するために、サーバーで頻繁に実行される一連のイベントをオンにして、同じ再生ワークロードを実行するオーバーヘッドを調べることができます。 SQL Serverで最も頻繁に実行されるイベントの2つは、lock_acquiredイベントとlock_releasedイベントです。これら2つのイベントのオーバーヘッドを比較するために、次のイベントセッションを使用できます。これは、述語なしでイベントを収集し、すべての実行が収集され、event_counterターゲットを使用してそれらが発生する頻度をカウントします。

    CREATE EVENT SESSION [locking Overhead] 
    ON SERVER
    ADD EVENT sqlserver.lock_acquired,
    ADD EVENT sqlserver.lock_released
    ADD TARGET package0.event_counter;
    GO

    リプレイワークロードの場合、これら2つのイベントは約111,180,000回発生します。これらのイベントの収集に関連するオーバーヘッドは、表3と図4に示されています。


    表3–ロックオーバーヘッドの比較


    グラフ4–ロックイベントのオーバーヘッドの比較

    データからわかるように、これらのイベントのパフォーマンスへの影響は、query_post_execution_showplanの場合よりも大幅に低くなります。ただし、ロックイベントセッション定義は、すべてのイベントをサーバーで発生させるように構成されていますが、全体のオーバーヘッドは全体で1%未満でした。 。ロックイベントセッションは500倍以上のイベントを評価したことに注意してください。この場合、すべてのイベントは実際にイベントセッションで発生する必要があり、query_post_execution_showplanイベントは評価後に実際に発生する必要はありませんでした。

    概要

    query_post_execution_showplanイベントは、実行するステートメントの実際のクエリプランを収集する機能を提供しますが、イベントを評価するためだけのデータ収集のパフォーマンスへの影響により、本番環境での使用には適していません。少なくとも、本番ワークロードに対してこのイベントを使用する前に、オーバーヘッドを考慮する必要があります。 Microsoftが提供するイベントの説明でさえ、イベントがパフォーマンスに大きな影響を与える可能性があることを認めています(私の強調表示):

    SQLステートメントが実行された後に発生します。このイベントは、実際のクエリプランのXML表現を返します。 このイベントを使用すると、パフォーマンスのオーバーヘッドが大きくなる可能性があるため、特定の問題を短時間トラブルシューティングまたは監視する場合にのみ使用してください。

    イベントの説明は、sys.dm_xe_objectsカタログビューの説明列、または図5(私の強調表示)に示すように新しいセッションUIにあります。


    図5–新しいセッションUIからのイベントの説明

    本番環境で実際に使用する前に、説明にこの警告が含まれているイベントのパフォーマンスをベンチマークすることをお勧めします。


    1. SQLServerでセッションのANSI_NULLS設定を確認する方法

    2. スプレッドシートとデータベース:切り替える時が来ましたか?パート1

    3. SQLでの順序付けされていない結果

    4. OracleのSELECTクエリから変数を宣言してその値を設定する