16コアと64 GBのAWSインスタンスでSQL Server Express 12.0.4100を実行していますRAM 3TBおよび9000 IOPS EBSが接続されています。これは2年間完全に実行され、今週まで発行します。
サーバーは1秒あたり5〜10のリクエストを受信するWebアプリを実行しており、各リクエストは異なるパラメーターを使用してのみデータベースへの同じクエリに変換されます(これはすべてORMによって処理されます)。これらのクエリ(GetProductクエリと呼びます)は、13のテーブルからデータを取得して、単一のJSON応答を作成し、ユーザー。クエリの実行には通常800〜1500ミリ秒かかります。
今週、クエリを実行すると、GetProductクエリによってもスキャンされるテーブルのwhere条件が1つある単純な選択トップ1000に気づきましたSQL Management Studioによって報告されたデータベースI/O使用量は、クエリが既に返されている場合でも、30MB/sから50MB/sの間で変動します(通常のデータベースI/Oは0.1MB/sから1MB/sです)。 GetProductクエリが突然完了するまでに60秒以上かかっていることが突然わかりました!タイムアウトを引き起こし、データベースに対して実行されるすべてのクエリは非常に遅くなります。サーバーボックス全体を再起動すると、これは修正され、非常に奇妙なクエリを再度実行するまで、すべてが正常に戻ります。
私はDBエキスパートとはほど遠いです。私はこのデータベースの保守も担当するプログラマーです。どのチームもデータベースの多くを知りません。統計を更新しましたが、ほとんどのインデックスで断片化が非常に高いことに気づきました(SSMSによって報告された95%から99%の間)。アプリを削除してすべてのインデックスを再構築できるように、メンテナンスウィンドウを計画しています。
断片化はこの種の動作を引き起こしますか?私はsp_whoisactive
を実行しましたが、自分のDBで他に何も実行していないと確信しています。GetProductクエリを呼び出すだけで、コンプリート。
[〜#〜]更新[〜#〜]
sp_whoisactive @get_plans = 1
がこのクエリに対してNULL query_plan
を返していたため、SSMSのアクティビティモニターの[最近の高価なクエリ]セクションを使用してクエリプランを取得しました。
ファイルが大きすぎてGoogleドライブアカウントにアップロードしたため、Pastebinを使用できません。
sp_updatestats
を実行した後のクエリプラン。何らかの理由で、問題を引き起こしていた他のクエリが原因で問題が発生しなくなりました。 sp_updatestats
の実行後、問題が発生しますが、クエリが遅いクエリプラン: https://drive.google.com/open?id=1lWrlljgtrGnYPGLjCZe_Hq_uCNqaRHko実行中のクエリは次のとおりです。変更される唯一のパラメーターは@p__linq__0
であり、別のUUIDに置き換えられます: https://Pastebin.com/YnrCJVLW
最後に、クエリの完了に時間がかかる場合のsp_whoisactive @get_plans = 1
の出力を次に示します。
私の場合は明らかにうまくいった解決策を投稿したかった。私は先週末、メンテナンスのためにアプリを停止し、データベースのすべてのインデックスを(SMSS UIを介して)再構築し、続いて統計を更新しました。それ以来、問題が発生しなくなったことを嬉しく思います。
私はこの前に統計を再構築しましたが、それは役に立ちませんでした。問題がインデックスの断片化に関連している場合、クエリは常に遅くなるはずですが、何らかの理由で、私の場合は機能しました。
皆さん、時間と提案をありがとうございました!