實戰現網問題之sql 效能分析及處理
前段時間週末快11點了,收到前下屬小明的QQ訊息和電話
說遇到個很急的問題,公司在做個活動,但伺服器經常掛,就算重啟伺服器, 15分鐘後,rds資料庫cpu就會到 100%
把連線情況發了個圖過來
通過以上截圖,給他分析了下:
在連線數 500 以下的情況,同一查詢居然佔滿了CPU所有資源,第一感覺是此 sql 肯定沒使用到索引或此sql過於繁雜,當然還有個疑問就是為什麼此 查詢量會這麼多?
由於是新活動,伺服器又掛了這麼久了,老闆一直在催,他實在搞不定,迫於壓力向我求助,但遠端還是不方便支援,就邀請現場支撐下。
於是打個的士狂奔過去。
到了現場後,仔細分析了連線情況,從 sql 來看,是生成的,而小明找的確是自己寫的類似的 sql,很遺憾 方向錯了。
得冷靜下,想了些方案來進行處理:
1.要找根源則需要首先得找到此條 sql 的生成地點,然後重新手工寫,不自動生成,建立索引,加快資料獲取速度
2.採用快取減少此sql 的執行次數
經過一段時間排查後,終於找到了此 sql 生成地點,並單獨在資料庫中進行執行(應用伺服器已關閉),explan 分析了下,發現本身執行並不慢。
但仔細看程式碼後,發現一個很嚴重的程式碼問題,導致此 sql 的查詢量非常巨大,然後資料庫崩了。
以下為大概寫法:
class A {
public B b;
public B getB(){ // 查詢資料庫,獲取此物件}
}
//重點的是下面的程式碼
A a=new A();
a.b.屬性1
a.b.屬性2
a.b.屬性3 .......
實際上每次在訪問 b 的任意屬性時,都會重新從資料庫獲取最新資料,資料庫怎麼可能不被搞死,新活動使用者量本來就大,併發量多一點點,使用者點著點著,資料庫直接崩了。
找到原因後,採用方案2處理,問題解決(後面幾天也有溝通,同樣或更多連線數,資料庫CPU佔用率低於10%)。
解決後,順便給他推薦了能提高效率的工具, play 區域性編譯工具,他用著評價不錯
總結:
sql 多采用 explan 分析下,索引很重要
寫程式碼真不能圖快,圖快往往是在挖坑,要注重效能及基本原則。
一旦後續使用者數爆增的情況下,就得多采用快取及資料庫讀寫分離 或分散式應用來解決,sql 效能瓶頸也需要非常關注。