すべてのインデックスの統計を更新しましたが、このクエリは実行に40秒近くかかります。私はそれが20歳未満である必要があります。私はDBAではなく、実行計画を読むのが初めてです。このクエリのパフォーマンスを向上させるために役立つあらゆる支援をいただければ幸いです。
クエリは、約2秒のCPU時間のみを使用します。これは、実行プランのルートノードで確認できます。いろいろなものを待つのに約30秒かかりました。
その待機時間の7915ミリ秒は ASYNC_NETWORK_IO 待機タイプ用です。この待機タイプは、SQL Serverがクライアントにデータを送信する準備ができているが、クライアントがまだデータを受信する準備ができていることを示していない場合に発生します。これは、SSMS結果グリッドで大きな結果セットを表示するときによく見られます。アプリケーションでこれと同じタイプの待機が発生している場合は、返された結果セットを処理するコードを調べ、不要な列が返されていないかどうかを確認してください。それ以外の場合は、クエリのパフォーマンスをより正確に測定するために 結果セットを破棄する が役立ちます。現状では、20秒の目標のうち8秒を失います。
これらのハッシュ結合を使用して少量のデータをこぼしますが、その結果、クエリの実行が劇的に遅くなります。私のローカルマシンで同様の結果を配置できます。
流出して加わるまでに約0.289秒かかります。これは、サーバーで発生するよりも約33倍高速です。使用しているクラウドプラットフォームを管理できない場合があることを理解しています。ただし、クエリを手動で調整する時間のシンクは、他のソリューションとのバランスを取る必要があります。クエリは、2秒のCPU時間しか消費しません。より優れたハードウェアがあれば、コードの変更を必要とせずに20秒未満で簡単に終了できます。率直に言って、もし誰かが私にVMを与えてくれて、あなたが見ているものと同じくらいのパフォーマンスが悪いなら、私はそれを使うのを拒否します。
より優れたハードウェアを入手できない場合は、MIN_GRANT_PERCENT = 99
クエリヒントを追加することで、流出することなくクエリのパフォーマンスをテストできるはずです。パフォーマンスが大幅に向上する場合は、ハッシュ結合に入るカーディナリティの見積もりを改善してください。 tempdbのスピルが発生するのは、実際の行数が推定行数よりも約20倍多いため、メモリ付与が小さすぎるためです。
この複雑な述語が問題の一因となっている可能性があります。
@Now BETWEEN OPL.StartDateUTC AND COALESCE(DATEADD(MILLISECOND, -3, CAST(CAST(DATEADD(DAY, 1, OPL.EndDateUTC) AS DATE) AS DATETIME)), DATEADD(MILLISECOND, -3, CAST(CAST(DATEADD(DAY, 1, @Now) AS DATE) AS DATETIME)))
試すべきことの1つは、Organization
テーブルとOrganizationProductLanguage
テーブルの結合の結果を一時テーブルに入れることです。一時テーブルを使用すると、クエリオプティマイザーは、1.41312ではなく、そのステップから12行を取得していることを認識します。それだけで、tempdbの流出を回避するのに十分な推定値が増える可能性があります。
Tempdbの流出を修正した後もパフォーマンスが許容範囲を超えている場合は、既に使用されている非クラスター化インデックスに追加の列を含めることで、キールックアップの一部を削除してみてください。影響の大部分は、ActivatedDateUTC
列とInactivatedDateUTC
列を[ProductAsset].[UX_ProductAsset]
に追加することから生じると予想しています。 DataValue
を[AssetCacheData].[IX_AssetCacheData]
に追加することで得られるメリットは少なくなります。このサーバーはI/Oにこのような大きなペナルティを適用するため、これにより、クエリの実行時間が通常予想されるよりも改善される可能性があります。