1. 程式人生 > >實戰現網問題之sql 效能分析及處理

實戰現網問題之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 效能瓶頸也需要非常關注。