背景
近幾日,公司的應用團隊反應業務系統突然變慢了,之前是一直比較正常。后與業務部門溝通了解詳情,得知最近生意比較好,同時也在做大的促銷活動,使得業務數據處理的量出現較大的增長,最終系統在處理時出現瓶頸。
分析和追蹤問題的根源
首先:通過工具追蹤服務器的性能,主要定位什么資源、在什么時候出現瓶頸。
這樣的工具很多,可以網上搜搜工具和使用方法如PerMon和PAL等,最終得到結果是在業務高峰期(中午12點到23點前)如下圖,CPU資源使用率一直很高,初步可以判斷是CPU資源緊張。那真的“資源”不夠嗎?!不一定,進一步分析。
下一步,要更進一步實時監測到底什么東西在消耗CPU資源。
可以實時監控SQL Server資源的工具也很多,我這里使用的SQL Server Profiler,通過過濾和篩選相關Event后抓取想要的列,最主要是CPU這一列的值,如下:
上圖,查看每一列CPU資源使用情況,看起來是不是很累,還好有另外一個國外很好的工具ClearTrace,它可以很輕松地分析出trc文件中最占資源的如CPU/Reads/Writes等,這里重點分析CPU,如下圖標出,第一二行就是導致CPU資源瓶頸的SQL語句
下一步,重點單獨調試、分析上面列出的有問題語句。
我采用做法是將上面拷貝出來並填寫對應條件參數的值,將整個語句拿到SSMS中單獨調試,開啟Actual Execution Plan和IO、Time統計,如下圖顯示單次執行logical read接近8.5w次,執行計划顯示查找是通過索引掃描,這個表比較大,所以查詢效率很低。而恰恰在這個案例中該語句執行頻率極高,最終給資源特別是CPU造成很大損耗。
這里推薦大家另外一個不錯的執行計划分析工具sqlsentry plan Explorer。
接下來,試着在QA環境中,根據語句條件加上合適的非聚集索引。
看一下效果如下圖,logical reads降到個位數,加上非聚集索引后,執行計划走的Index Seek,查詢效率極大提升。
最后,實施到生產環境后,查看優化效果。
總結
很多時候,當我們遇到系統性能問題,需要先收集數據后,再通過數據分析確定問題根源。本案例在日常數據庫運維中比較典型的,常規入手點就是檢查PerfMon輸出,已識別Memory、I/O 、CPU的瓶頸,資源瓶頸可能就是來自於某個或幾個執行效率特別差的查詢語句,經過適當的數據收集、分析處理基本可以鎖定根源,並通過適當的方法如調整索引、調整語句寫法等基本可以解決主要性能問題,特別是在系統上線不久這些問題尤為明顯。另外就是隨着時間推移,系統的業務壓力增加,數據量增加也會帶來類似性能問題。總的來說,建議一定要先從應用層面、數據庫中索引、存儲過程代碼等最基本的方面入手進行調優,最大程度榨取提升性能的空間,然后再考慮數據庫配置、硬件等。另外特別提醒,解決一個瓶頸可能帶來另一個瓶頸,所以建議對調優的內容做一段時間的監控。