web-dev-qa-db-ja.com

クエリとプランはまったく同じですが、期間と読み取りの合計が異なります。パラメータスニッフィングは知っていますが

パラメータスニッフィングとは何か知っていますが、これは異なるようです。次の簡単なクエリを使用します。

select * from A400RDATA

このテーブルにはcluster indexと約25000行。クエリは通常1秒かかりましたが、今では20秒かかりました。

私はその実行プランをキャッシュで見つけ、sp_BlitzCache(Brent Ozarに感謝)すべての詳細を分析してください->確かに、最後の実行には20秒かかります。

そこで、少し変更を加えて先頭のスペースを空けて、このクエリをもう一度実行します: "select * from A400RDATA "(s of selectの前に先行スペースがあることに注意してください。)先行スペースはクエリテキストの変更なので、SQL Optimizerは新しいクエリプランを生成します。

2つのクエリプランは同一であり、簡単なプランであり、cluster indexですが、読み取りの合計と期間は異なります。 2つの異なるBlitzCache結果に従います。

enter image description here

ソーラーウィンドはPage Life Expectancy、およびSQL Serverインスタンスは1つのコア(MAXDOP = 1)。
MAXDOPPLEが問題の原因になっていると思いますが、どう思いますか?どうすればそれを確認できますか?
データがディスクまたはRAMから取得されたかどうかを確認するにはどうすればよいですか?

20秒の実行プランの論理読み取りと物理読み取りを確認しました。

  • 実行時間:3
  • 物理読み取り:0
  • 処理された行:76000
  • 論理書き込み:0
  • 論理読み取り:3841

物理的な読み取りはありません....... PLEが原因ではない可能性があります(おそらく)。プランの詳細をもう一度読みました:3回の実行と合計所要時間の20秒なので、各実行には6秒かかりましたが、CPU時間は比較的わずかでした:

  • 合計時間(ミリ秒)= 20,013.84
  • 合計CPU(ミリ秒)= 192.57

CPUに問題がありますか?おそらく1つのCPUだけでは不十分であり、SQLはクエリをRUNNABLE状態(CPU時間待機)にします。

4
Gio

2つのクエリプランは同一で、簡単なプランであり、クラスターインデックスを使用するだけですが、読み取りの合計と期間は異なります。 2つの異なるBlitzCache結果に従います。

その結果セットの合計読み取りは、複数の実行にわたって合計される可能性が最も高いです。合計行の列が76,218であることを確認しますが、最小、最大、平均は他の実行と同じですか?これは、元の計画が3回実行されたことを示唆しているので、合計ではなく、平均である平均を見てください。

これらの読み取りは論理的であるか物理的であるかを確認する必要があります。実行時間の違いにより、読み取りが論理的である可能性が示唆され、物理的な読み取りの違いにより状況がさらに明らかになる可能性があるためです。

ソーラーウィンドはページの期待寿命の低下を示し、SQLサーバーインスタンスは1つのコアのみを使用します(MAXDOP = 1)。 MAXDOPとPLEが問題の原因になっていると思いますが、どう思いますか?どうすればそれを確認できますか?データがディスクまたはRAMから取得されたかどうかをどのようにして知ることができますか?

コアが1つしかない場合、両方のクエリの実行でMAXDOP = 1が使用されるため、ばらつきが生じる可能性はほとんどありません。 PLEは、パフォーマンスの問題を引き起こしているより深い問題の症状である可能性がありますが、根本的な原因ではありません。 PLEが一貫して低い場合、または極端な鋸歯状のパターンがある場合は、その原因を特定することで、このクエリの問題を特定できる場合があります。

クエリにはWHERE句がないため、説明している内容はパラメータスニッフィングのようには聞こえません。クエリは最初の実行(物理読み取り)時にディスクからページをバッファーキャッシュに読み取る必要があり、後続の読み取りは通常、物理読み取りよりもはるかに高速なメモリ(論理読み取り)で行われているようです。

物理読み取りと論理読み取りの説明については、 この記事 を参照してください。基本的に、最初に実行したときは20秒かかりましたが、これはディスクからページを読み取ることが原因です。ささいな変更または新しいプラン(実際のプランは同じでした)のため、次の実行は速くなりませんでしたが、これらのデータページがディスクではなくメモリから読み取られたためです。バッファキャッシュをフラッシュしてクエリを再実行すると、同じ動作が発生する可能性があります-1回目の実行= 20秒、2回目の実行= 1秒。

この動作を強制的に実行して、リアルタイムで確認できます。 非本番サーバーで、次を実行します:

DBCC DROPCLEANBUFFERS

SET STATISTICS IO ON

SELECT * FROM A400RDATA

SET STATISTICS IO OFF

メッセージペインの出力を確認し、物理読み取り値と論理読み取り値を書き留めます。以下の行をもう一度実行します。

SET STATISTICS IO ON

SELECT * FROM A400RDATA

SET STATISTICS IO OFF

出力を確認し、物理読み取り値と論理読み取り値を再度比較します。物理読み取りは大幅に、おそらく0に低下しているはずです。論理読み取りは同じかそれ以上になり、ディスク読み取りにフォールバックする必要なく、ページがメモリから読み取られるようになります。実行時間も速くなるはずです。

すでに実行されたクエリの本番環境でこれをどのように確認しますか?まあ、事前に監視とメトリックの収集を行わなければ、確定することは困難ですが、クエリ sys.dm_exec_query_stats を使用してプランハンドルを使用すると、最近の実行に関する統計を取得できます。最後、最小および最大の物理読み取りを確認します。 minが0で、maxがそれより大きい数値の場合、一部の実行がディスクから読み取られていることを示しています。クエリの実行が1秒に戻った場合、lastは0または非常に小さい数値である必要があります。

また、そのDMFからの最後、最小、および最大経過時間の列をチェックして、20秒の実行プランの実行時間に差異があるかどうかを確認します。 PLEの低下は、これらのデータページが古くなった、またはキャッシュから強制的に取り出され、物理的な読み取りが増加したことを示す可能性があるため、SolarwindsはPLEの低下とこのクエリの実行時間の増加を関連付けるのに役立ちます。サーバーのパフォーマンスを維持するためのPLEの最適化/管理に関する有用なヒントについては、 この記事 を確認してください。

4
HandyD