Microsoft CertifiedMasterのBrentOzarは最近、SQL Serverの並列処理、特にQuestのDatabase Training DaysFallSeriesの最終回で待機タイプCXPACKETとCXCONSUMERについて説明しました。ブレントはいつものユーモラスでアクセスしやすい方法で、並列処理の概念をわかりやすく説明し、CXPACKETとCXCONSUMERの待機統計が多すぎる場合の処理方法を説明しました。
まず、並列処理とは何ですか。SQLServerでクエリを並列実行するのはなぜですか。
簡単に言うと、SQL Serverは、特定のクエリに大きなワークロードがあることを自動的に認識し、1つだけではなく複数のプロセッサ間で作業をより効率的に実行できると判断します。これは一般的に賢明な決定ですが、SQL Serverがタスクを実行するスレッド間で負荷のバランスをとらないと、問題が発生する可能性があります。
CXPACKETおよびCXCONSUMERの待機タイプについて
CXPACKETとCXCONSUMERは、作業のバランスが取れていないことを示す待機タイプです。サーバーでこれらの待機統計を確認すると、SQL Serverがクエリを並行して実行していることがわかりますが、使用可能なプロセッサ間でクエリを分散するという優れた仕事をしていません。
すべてのデータベースの専門家は、リソース消費の観点からクエリを実行するのにどれだけのコストがかかるかを表す「コスト」の概念に精通しています。これらの「クエリバックス」は、作業のおおよその尺度であり、クエリが並行して実行されるかどうかに関する重要なシグナルです。安価なクエリを並行して実行する必要はありませんが、高価なクエリを並行して実行する必要があります。目標は、クエリを可能な限り迅速かつ効率的に実行して、次の行を開始できるようにすることです。 SQL Serverはスレッドをスケジューラーとして指定し、ブレントが「ロボットの大君主」と見なしたこのスレッドは、並列ワークロードの一部をワーカースレッドまたは「ロボットミニオン」に割り当てます。
並列処理とロボットの大君主
ブレントは、これがどのように機能するかを示すためにデモに飛び込みました。彼は、Stack Overflowデータベースを使用して、インデックスが存在するために非常に高速な低コストのデータベースルックアップを作成しました。実行プランは非常に単純で、実行に並列処理は必要ありませんでした。
しかし、彼がインデックスにないもののルックアップを導入したとき、テーブルのクラスター化されたインデックスのすべての行に対してキールックアップを強制することで状況が変わりました。 SQL Serverは、これは大変な作業になることを認識していたため、並列処理を導入し、実行プランにアイコンでそのように示しました。実行プランが3次元の場合、複数のスレッドが積み重なっていることを確認できますが、そうではないため、統計を表示して、各CPUスレッドによって実行される論理読み取りなどの情報を確認する必要があります。
>ただし、SQL Serverは、このタスクをすべてではなく、いくつかのスレッドにのみ割り当てました。ブレントは、並列アイコンを超えて発生することはすべて、割り当てられたプロセッサでのみ発生していると説明しました。したがって、最初の読み取りを実行したスレッドだけが、キールックアップも実行するようになりました。ロボットの大君主は、すべてのミニオンにピッチインするように依頼するのではなく、少数のミニオンにタスク全体を実行するように依頼しただけです。
彼はさらに、SQL Serverはスレッドが実行していることを説明し、ロボットの大君主が実行していることを追跡する必要があることを説明しました。初期の頃は、このすべての作業は1つの待機統計で表されていましたが、何があっても、すべてのスレッドが機能している間、オーバーロードは待機する必要があるため、これは意味がありませんでした。そこで、新しい待機タイプが導入されました。これはCXCONSUMERであり、スケジューラー/オーバーロードスレッドが実行していることを追跡し、CXPACKETはワーカー/ミニオンスレッドが実行していることを追跡します。
ブレントはクエリに戻り、並べ替えを追加してさらに複雑にしました。これで、操作をより効率的にするのではなく、並列処理が問題を引き起こしていることがさらに明らかになります。作業は、いくつかのワーカースレッド間でさらに不均衡になり、一部のスレッドではメモリが不足してディスクに流出しています。彼は参加を追加し、非稼働中のコアからの支援を受けていない稼働中のコアにさらに負担をかけました。 CXPACKETの統計は上昇を続けました。
この状況であなたは何ができますか?並列処理の決定は、クエリレベルではなくサーバーレベルで行われるため、構成を変更する必要があります。
主要な構成の評価
クエリコストが特定のレベルよりも高い場合、SQLServerが並列化されることはすでに学びました。小さなクエリは単一のスレッドに制限されます。しかし、何がしきい値を制御しますか?これは、並列処理のコストしきい値(CTFP)と呼ばれるプロパティです。デフォルトでは、実行プランでコストが5クエリドルを超えると判断された場合、クエリは並列化されます。これを設定する方法についてのガイダンスはありませんが、ブレントは50より大きい数を推奨しています。これにより、些細なクエリの並列処理がなくなります。
もう1つの構成は、SQL Serverがクエリに割り当てるスレッドの数を表す最大並列度(MAXDOP)です。ここでのデフォルト値はゼロです。これは、SQLServerが64までの使用可能なすべてのプロセッサを使用してクエリを実行できることを意味します。 MAXDOPオプションを1に設定すると、SQL Serverは1つのプロセッサのみを使用するように制限されます。つまり、シリアルプランでクエリを実行する必要があります。 SQL Serverは、使用しているサーバーコアの数に基づいてMAXDOP値を推奨しますが、すべてのコアが必要になることはあまりないため、通常はMAXDOPを低くするのが理にかなっています。
ブレントはこれら2つの構成を調整し、クエリを再度実行しました。今回は、より多くのコアが並列動作に関与していることがわかりました。 CXPACKETの待機統計は低く、これは負荷が以前よりも多くのコア間でより均等に分散されたことを意味します。
CXPACKETおよびCXCONSUMER待機統計と戦うためのヒント
過剰なCXPACKETおよびCXCONSUMER待機統計が表示される場合、ブレントは次の手順をお勧めします。
- 業界のベストプラクティスに従ってCTFPとMAXDOPを設定し、それらの設定を数日間焼き付けます。これにより、プランキャッシュがクリアされ、SQL Serverにクエリ実行プランの再構築が強制されます(コストを再評価します)。
- インデックスを改善して、クエリが並行してスキャンと並べ替えを行う時間を短縮します。新しいインデックスをベイク処理してから、まだ多くの作業を行っているクエリを探します。
- これらのクエリを調整して、数日間焼きます。
- 最後に、並列処理が依然として深刻な問題である場合は、並列処理の問題がある特定のクエリを探し始めます。
さらに詳しい洞察を得るために、CXPACKETおよびCXCONSUMERの待機統計に関するブレントのトレーニングセッション全体をオンデマンドで以下で確認できます。