web-dev-qa-db-ja.com

推定実行プランを表示すると、CXPACKET、PAGELATCH_SH、およびLATCH_EX [ACCESS_METHODS_DATASET_PARENT]待機が生成されます

Microsoft SQL Server 2016 SP2-CU6(13.0.5292.0)を4 vCPUで実行していますVM with max degree of parallelism に設定 2およびcost threshold for parallelism に設定 50

午前中に SELECT TOP 100の推定実行プラン クエリを表示しようとすると、大量の待機が発生し、推定プランをレンダリングする操作に数分、多くの場合5〜7分かかります範囲。繰り返しますが、これはクエリの実際の実行ではなく、Estimated Execution Planを表示するためのプロセスです。

sp_WhoIsActive はどちらかを表示しますPAGEIOLATCH_SH待機またはLATCH_EX [ACCESS_METHODS_DATASET_PARENT]待機し、実行時に Paul RandalのWaitingTasks.sql スクリプトを実行中にCXPACKETが表示され、ワー​​カースレッドがPAGEIOLATCH_SH待機:

enter image description here

*リソースの説明フィールド= exchangeEvent id=Port5f6069e600 WaitType=e_waitPortOpen waiterType=Coordinator nodeId=1 tid=0 ownerActivity=notYetOpened waiterActivity=waitForAllOwnersToOpen

ワーカースレッドは、statsテーブル全体をメモリに移動しているようです(これらのページ番号と、Paul Randalのクエリから表示される後続のページ番号は、statsテーブルのクラスター化されたキーをポイントしています)。計画が戻ったら、さまざまなレコードのみが残っているstatsテーブルのほとんどがキャッシュから削除された後でも、残りの期間は基本的に瞬間的です(シーク操作によってプルされたと想定しています)同様のクエリ)。

クエリがSCAN演算子を使用するプランで実際に実行されている場合、この初期動作を期待しますが、上記のリンクされたプランに示されているように、実行プランを評価してSEEK演算子のみに到達するときになぜこれを行うのですか?ここでパフォーマンスを向上させるために何ができますか(このステートメントを営業時間前に実行して、データが適切にキャッシュされることを除いて)。 1組のカバーするインデックスが有益だと思いますが、それらは動作の変更を本当に保証しますか?ここでは、いくつかのストレージおよびメンテナンスウィンドウの制限内で作業する必要があり、クエリ自体はベンダーソリューションから生成されるので、この時点では(より良いインデックス作成以外の)他の提案を歓迎します。

13
John Eisbrener

実際の実行プランのリクエストにより統計更新がトリガーされたようです。これは午前中に発生するとのことですが、関連するテーブルに多くの変更を加える夜間のプロセスがあると思いますか?

したがって、SQL Serverは統計を使用して計画を作成し、変更しきい値に達し、操作の一部として統計の自動更新を実行します。

あなたが共有した推定計画のXMLに、今朝の統計の近くにある更新日が表示されています。

LastUpdate="2019-05-06T09:12:49.92"
LastUpdate="2019-05-06T09:12:58.3"
LastUpdate="2019-05-06T09:13:20.33"
LastUpdate="2019-05-06T09:13:09.67"
LastUpdate="2019-05-06T09:12:59.05"
LastUpdate="2019-05-06T09:12:39.56"

これらが非常に大きくてビジーなテーブルである場合(おそらくサンプリングの割合に基づいているようです)、統計の更新に大量の馬力がかかっていることは驚くべきことではありませんtoo

13
Josh Darnell

SSMSで長い計画時間が表示される場合、可能性の高い順に次のいずれかになります。

  1. クエリオプティマイザーは、統計を作成または更新する必要があると判断しました。
  2. 推定されたプランのサイズは非常に大きく(たとえば、10 MBを超える)、SSMSを表示するのに長い時間がかかるだけです。
  3. クエリのコンパイル自体は、CPU使用率が十分に高い計画を探すために、実際には長い時間がかかりました。
  4. サーバーは極端な強迫下にあります。たとえば、 gateway が利用可能になるのを待つ必要があるかもしれません。
  5. コンパイル時間が非常に長くなるさまざまなバグ。

あなたの状況では、答えはほぼ確実にSQL Serverが統計を更新または作成していることです。いくつかの手がかりがあります。クエリプランのサイズが小さく、クエリプランが比較的シンプルで低コストであり、コンパイルCPUがコンパイル時間よりも大幅に短い場合:

enter image description here

新しい寄稿者 Josh Darnell は、XMLの統計の最後に更新された時刻の手掛かりも指摘しました。

SQL Server 2019では、クエリが統計の更新を待機しているときに、新しい待機タイプ WAIT_ON_SYNC_STATISTICS_REFRESH が導入されています。そのバージョンでは、この問題を診断する方がはるかに簡単です。それまでは、間接的な手法に頼る必要があります。

回避策には、メンテナンス期間中の統計の更新、またはデータベースの統計の自動更新非同期の有効化が含まれます。変更する前に、そのオプションの完全な影響を理解してください。クエリプランは、統計の更新後ではなく、統計の更新前に作成されます。大きな利益になる可能性のある一部のワークロードの場合。他の人にとっては、善よりも害を及ぼす可能性があります。

9
Joe Obbish