SQL Server 2014の突然のスローダウン/挿入なし/ハードウェアまたはインデックスに関連しない


8

350GBPCで約4,000万行のデータベースを実行しています。

SQL Server 2014、Win7、AMD 8350 @ 4.8GHZ、16 GBのRAM、500 GB SSD(データベースは、500 MB / 500 MBの読み取り/書き込みのスループットで、独自の500 GB SSDでホストされています)。

データベースは更新されていません。分析/読み取りを行っています。少数の作成をindexes、任意のjoincount(*)など、私の目的のためにokです1分未満を取ります。私はデータに対していくつかのクエリを実行しており(単一の結合クエリを実行した後、40〜50回実行すると遅くなります)、1分かかった呼び出しが20分後にまだ実行されています。

私はシステムリソースを注意深く監視しておりSSD、クエリの開始時にキックインを確認できます。クエリが20〜30秒間読み取り121kB/second、次に次の20分間読み取ります。これは、CPUの問題やディスクの問題ではありません。私はRAMの容量に制限がありますが、データベースを最初にロードしたときに呼び出しは正常に実行されましたが、25分後、何も実行されません。

事実上、データベースにクエリを実行することはできませんSELECT。基本的なステートメントでさえ、呼び出しには非常に時間がかかります。インデックスの再構築と統計の更新を試みましたが、違いはありません。

私はこれについて多くの経験を持っていないので、SQLクエリが正しくない可能性があります。その場合、エラーが発生するか、または結果が0で実行を終了する可能性がありますが、どちらも発生しません。

私がやろうとしていることは、テーブルACALLSに基づいて、時間の5秒前に「TypeID」のすべてのインスタンスをカウントすることです。

SELECT ACALLS.StartTime, ACALLS.Time, ACALLS.ServerIP, ACALLS.SRVR,   ACALLS.calls, ACALLS.TOKEN, COUNT(TypeID) as ExecRate
FROM ACALLS
INNER JOIN MAINVIEW ON 
MainView.TimeStamp BETWEEN ACALLS.StartTime and DATEADD(ss,-5,ACALLS.StartTime)

WHERE DATEPART(hour,MainView.TimeStamp) BETWEEN 10 and 13 and 
CAST(MainView.TimeStamp as date) = '2015-12-09' and
MainView.TypeID = '123456789'
GROUP BY Acalls.STartTime, ACALLs.TIME, ServerIp,SRVR, ACALLS.CALLS, ACALLS.TOKEN
ORDER BY Acalls.StartTime

「Who is Running」を実行した後、 ここに画像の説明を入力してください ここに画像の説明を入力してください


これは、テーブルの統計と、結合に対して行われた処理のタイプに関係していると思います。クエリの実行プランを確認する必要があります。ネストされたループ結合は問題の兆候である可能性があります。
ゴードンリノフ2016

WITH RECOMPILEを試しましたか?

3
驚くほど遅いクエリの実際の実行計画を投稿します。クエリは単純であるほど優れています。
usr

1
すべてのテーブルの統計を更新しましたか?すべてのインデックスを再構築しましたか?情報sp_whoisactiveリンク
TT。

2
これらの待機統計は多くのIOを示していますが、クエリのどの割合がIOで何がCPUであるかはわかりません。結果を投稿するために推奨したテストを実行します。
usr

回答:


2

SARG非対応のクエリがあります。適切なインデックスがあっても、そのクエリでそれらを使用していません。

最初に、pageiolatch_shに対する反応は、ディスクからバッファーにページを読み取ることです。プルしようとしているデータのための十分なRAMがありません。

次に、実行プランとそのインデックスの使用方法、またはその欠如を確認する必要があります。

結合とWHEREで関数を使用するのをやめ、絶対に必要なデータのみを取得してください。

  • "BETWEEN ACALLS.StartTime and DATEADD(ss、-5、ACALLS.StartTime)"-BETWEENでそのDATEADDを削除します。

    • これが読み取り専用のレポートデータベースである場合は、必要なデータのみを含むレポートテーブルを作成し、必要に応じて複合インデックスを配置します。その1つを使用して、必要なACALLS行の主キー/その他の一意のキーを取得し、後で残りのACALLSデータを取得します。
  • WHERE DATEPART(hour、MainView.TimeStamp)BETWEEN 10 and 13およびCAST(MainView.TimeStamp as date)= '2015-12-09'

    • 同じこと-CASTを取り除く-'2015-12-09'をMainView.TimeStamp> = @StartTimestamp AND MainView.TimeStamp <@EndTimestampの正しいデータ型の1つまたは2つの@パラメータに変更します

    • また、@ StartTimestampと@EndTimestampを制限して時間基準も含めることにより、そのDATEPARTを削除します。

おそらく、結合の前に、これらのMainView条件を満たす行の主キー/一意キーのみを含む#tempテーブルをロードします。

うーん...また、Mainviewが複雑なビューの場合は、ベーステーブルに直接移動して、その#tempテーブルをロードします。

プロファイラを使用して、#tempまたは他のステージングテーブルにインデックスを追加(必要に応じて複合)することが純利益または純損失であるかどうかを確認することを忘れないでください:)。


1

mainview(typeid、timestamp)に複合非クラスター化インデックスを作成します。

mainviewの「where」を変更して、mainview列に対する関数を使用しないようにします。これらをより動的にする必要がある場合は、クエリを実行する前にこれらの値を変数として事前計算する必要があります。

WHERE MainView.TimeStamp BETWEEN '2015-12-09 10:00' and '2015-12-09 13:00'

ACALLS.StartTimeに非クラスター化インデックスを作成します。

結合をACALLSに変更して

WHERE ACALLS.StartTime BETWEEN DATEADD(ss,-5,MainView.TimeStamp) AND MainView.TimeStamp

私の理解から、それはあなたのロジックを処理し、かなり高いパフォーマンスで参加し、IOから離れます。

あなたが実行しているものについての私の最良の推測は、データがキャッシュからフラッシュされているか、tempdbが時々ディスクに流出していることです。そのため、私が通常見つけた最良の解決策は、 tempdbとメモリの使用を制限すると、根本的な問題がなくなります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.