SQL Server - 執行查詢後磁碟活動非常高?
我在 AWS 實例上執行 SQL Server Express 12.0.4100,該實例具有 16 個核心和 64 GB RAM,並附加了 3TB 和 9000 IOPS EBS。這已經完美執行了 2 年,直到本週都沒有出現任何問題。
伺服器正在執行一個每秒接收 5-10 個請求的 Web 應用程序,每個請求都被轉換為對數據庫的相同查詢,只是使用不同的參數(這都由 ORM 處理)。這些查詢(我們稱之為GetProduct查詢)有點大,因為它們從 13 個表中檢索數據以建構一個發送回使用者的 JSON 響應。查詢通常需要 800 到 1500 毫秒才能執行。
本週我注意到,當我執行一個查詢時,一個簡單的 select top 1000 與一個表中的單個 where 條件也被GetProduct查詢掃描 SQL Management Studio 報告的數據庫 I/O 使用率在 30MB/s 之間波動和 50MB/s,即使我的查詢已經返回(正常的數據庫 I/O 在 0.1MB/s 和 1MB/s 之間)。我突然發現我的GetProduct查詢現在需要 60 多秒才能完成!導致超時和對數據庫執行的所有查詢變得非常慢。如果我重新啟動整個伺服器框,則此問題已修復,一切都會恢復正常,直到我再次執行非常奇怪的查詢。
我遠不是數據庫專家,我是一名程序員,也負責維護這個數據庫,團隊中沒有人對數據庫了解太多。我更新了統計數據並註意到我的大多數索引上的碎片確實很高(SSMS 報告的碎片在 95% 到 99% 之間)。我正在計劃一個維護視窗,這樣我就可以關閉應用程序並重建所有索引。
碎片會導致這種行為嗎?我執行了
sp_whoisactive
,我確定我的數據庫上沒有執行其他任何東西,只是呼叫GetProduct查詢需要花費大量時間才能完成。更新
我使用 SSMS 活動監視器中的“最近的昂貴查詢”部分獲得了查詢計劃,因為為此查詢
sp_whoisactive @get_plans = 1
返回了 NULL 。query_plan
我無法使用 Pastebin,因為文件太大,所以我將它們上傳到我的 Google Drive 帳戶:
- 一切正常時查詢計劃,查詢執行時間不超過 1500 毫秒:https ://drive.google.com/open?id=1x3esroDgkdwz5XeRXbDjA5ygmQc_sZOF
- 執行後的查詢計劃
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),然後更新了統計資訊,我很高興地說從那以後我們再也沒有遇到過這個問題。
在此之前我已經重建了統計資訊,但它沒有幫助,如果問題與索引碎片有關,那麼查詢應該一直很慢,但由於某種原因,它在我的情況下有效。
謝謝大家,感謝您的時間和建議!