1. 程式人生 > >簡單的記錄一次簡單的優化

簡單的記錄一次簡單的優化

原因 循環 返回 嘗試 場景 業務場景 pre 這才 查看

#大致的業務場景

從一個報警表中查詢數據,報警表中有很多其他表的外鍵,比如報警的設備信息信息,報警的組織信息,報警的原件信息等等,也就是說查詢報警信息的時候可以查出來很多相關的信息,需求是參數傳一個組織id,要求查詢當前組織以及子組織的報警,同時實現分頁返回的功能,根據當前組織查詢子組織在數據庫中是有函數實現的。

# 最初的實現(超慢的那種)

從報警表中查出所有信息,然後根據外鍵再去其他表中查詢相關的信息,比如設備具體信息等。由於客戶端分頁需要返回符合查詢條件的總條數,所以還有一個count(1)的service; 寫完之後測試,發現幾千條的數據竟然查詢了4s,這。。。。。。簡直是不能忍啊,於是開始查找原因。

# 分析原因

思路很簡單,就是一部分一部分的查看運行時間,找出耗費時間長的代碼,最後發現3s是由於count(1), 也就是查詢總條數所耗費的時間,沒理由啊,走索引的話幾千條應該是毫秒級別的啊,直接在數據庫運行count(1)的sql發現需要1.5s左右,這。。。。。。。。為啥到代碼中就變成3s了???最後發現有一個邏輯是計算總頁數的代碼,大致是這樣寫的

if(aaService.getTotalNum % pagesize == 0){
     totalPage = aaService.getTotalNum / pageSize;
}else{
     totalPage = aaService.getTotalNum / pageSize +1;      
}

wtfk???

這不就相當於調用了兩次數據庫嗎???腦殘。。。嗯,說的就是你。。。。

於是改呀改的,好了,喜聞樂見,直接減少了50%的時間,嗯,初步取得一點成就,還是很開心的

但是。。。。。。。。。。。。 又一想,

這才幾千條數據就1s多,那像天貓這種nnnn多數據的豈不是要慢死,,但我並沒有發現人家慢啊。。。

好吧,剛想飛上天和太陽肩並肩,瞬間就被拽回地面。。。

繼續嘗試,之前的sql查詢類似是這樣的:

select count(1) from 報警表 where find_in_set(組織id, 查詢當前組織以及子組織的函數(當前組織id));

我試著吧where條件去掉,一查,我的哥。。。。。。。。。150ms,,這。。。。。。淩亂了,全表count竟然比部分還快。。。

猜測原因,應該是因為使用了查詢子組織的函數,導致count沒有走索引,,,,,

好了,既然找到罪魁禍首了,就好辦了,先查詢出來子組織然後再使用

select count(1) from 報警表 where 組織id in ();

果然,瞬間下降到150ms,哈哈哈,老天不負我,。。。。。。。。。

再回到上文,那還有其他的1s是怎麽出來的呢,

還記得我們是先把報警表的數據查出來然後在根據外鍵去查詢他的具體信息的吧,發現,有很多很多次連接數據庫的操作。

所以稍稍優化一下,在查詢報警的sql 中直接left join 其他表,把需要的相關數據在一條sql 中直接查出來,

其實就優化了這麽多,但是這個查詢就從4s直接降到了150ms,效果那是相當的顯著,一口氣都可以爬5樓了。。

# 總結一下,其實這次優化使用的方法並不多

第一個就是盡量減少連接數據庫的次數,特別註意的是千萬不要在循環中去連接數據庫查詢

第二個就是註意使用數據庫的索引

最近老加班。。。。。。這還是從王者榮耀中省下來的時間碼的字,寫的很粗糙,若有客官看到,還請見諒。。。

簡單的記錄一次簡單的優化