1. 程式人生 > >一次關於mongodb效能踩坑的總結

一次關於mongodb效能踩坑的總結

發現效能問題

上一次匯入資料後,發現系統十分的卡頓,但是才僅僅1000多條資料而已,怎麼會讓系統變得如何的卡頓呢?於是我開始走在排查系統卡頓的原因的道路上。

首先,先定位問題是出現在前端上還是後端上。開啟瀏覽器,輸入localhost:7000, 然後F12開啟netword。啟動後端專案,檢視log。切換回瀏覽器,右鍵重新整理。結果發現好多些問題:

  1. 請求傳送的個數比較多。
  2. 後端每個介面的響應時間都比較長,都超過了1s,這明顯有問題。
  3. 前端很多請求從: 傳送請求到頁面渲染成功所需要的時間大於了10S(傳送請求時間+後端介面響應時間+下載資源時間,即回傳資料時間+頁面渲染時間)。

從上面這幾個現象可以看出:

  1. 後端有明顯的問題。
  2. 前端暫時沒有什麼問題。

好好分析一下,為什麼後端每個介面的響應時間都會超過1s,mongodb是出了名的速度快,一般查詢資料就幾十ms,普通查詢也不會超過300ms。但是看到的介面響應時間卻是超過了1s,有的還是明顯3,4s。

苦苦冥想,細細推測,思來想去,都不知道是怎麼回事,最後只有採用刪程式碼的方式來定位問題了。

當刪除類似於下面的程式碼的時候

Schema.virtual('affixes', {
    ref: 'Affix',
    localField: '_id',
    foreignField: 'businessId',
});

這個時候,發現後端介面的響應時間正常了,可以判斷,這段程式碼起到了一定的作用,但是這只是簡單的連表查詢而已。為什麼就導致介面響應時間多那麼多呢?

我繼續分析,進入到controller.js裡面,將與表關聯查詢的程式碼找出來,終於,我快要發現元凶了,刪除這幾行程式碼,ok,同樣,響應時間正常了。

仔細分析這幾行程式碼,發現了一個很重要的事情: 居然是全表查詢!!而且是3張表關聯的全表查詢!!所以...查詢的資料差不多就是這個量: 2000 * 2000 * 2000, 也怪不得為什麼響應時間會超出1s了。

第一個元凶已經被抓住了。但是我還並不知道為什麼前端從請求到渲染成功的時間怎麼會超過10s,這簡直不能忍。

清空network,然後重新整理,重新發送請求,可以看見傳送了5個左右的請求,而檢視後端的log發現其中3個請求都是在做表關聯的全表查詢,並且reply的時候還是將所有的資料都返回到前端裡去了。

ok,現在我大概已經知道為什麼會有超過10s的響應時間了,下載的資料量也比較大,所以響應時間 = 傳送請求時間 + 後端處理時間 + 下載資源時間 + 渲染時間, 由於資料量比較大,所以導致最後的兩個時間也不小。

現在大概已經都找出了為什麼頁面會卡頓並且遲緩。原因就是沒有做後端分頁,系統裡用的是前端分頁。

效能優化總結

  1. 查詢資料避免多張表關聯全表查詢。
  2. 先過濾再關聯查詢,而不是先查詢再關聯表。
  3. react裡多個列表,一定要設定key。
  4. 分頁一定不要前端做,因為資料量大了肯定要崩掉的。