MongoDB在這裡比PostgreSQL慢了7倍

  • 2019 年 10 月 7 日
  • 筆記

編程應用、實戰教程,不容錯過

最近有需求,要將一個區域網Web數據平台遷移到線上,順帶著,本地服務使用的PostgreSQL也要替換成中國某雲的MongoDB。

由於之前的Web框架選擇的Django,為了能夠最小限度地改動程式碼,並對接上MongoDB上已存在的資料庫和數據,在一番對比之後(Djongo和MongoEngine),選擇了MongoEngine這個對象文檔映射(ODM)模組來替代Django原有的ORM。

對照著MongoEngine的文檔一頓操作,第一個頁面遷移完成,趕緊打開看看。

不看則已,一看瞎哭,頁面載入完足足等了1、2、3、4、5、6、7、8、……27秒

(線上MongoDB服務)

而之前的系統這個頁面打開只需要幾秒鐘:

(本地PostgreSQL服務)

這還了得,上線了不是給自己丟臉嗎,趕緊排查測試。

在這個頁面裡面,主要數據操作是從資料庫中查詢出原始數據,然後載入到Pandas的DataFrame中,接著在Pandas中進行各種數據處理,最後返回JSON數據給前端進行渲染。

資料庫總的數據量為接近500萬,最後的查詢結果在3萬左右。

對各個環節分別進行測試發現,主要的時間消耗在了從資料庫讀取數據,然後載入到Pandas這個過程中。

於是將這個過程專門提取出來,單獨測試其消耗的時間。結果發現,使用MongoEngine進行數據查詢,然後載入到Pandas中需要幾十秒的時間:

21秒的耗時,可能是由於MongoEngine對PyMongo進行封裝之後的性能不行吧,於是直接使用PyMongo進行測試:

果然,經過一層封裝之後,MongoEngine的效率不如PyMongo,但是直接使用PyMongo也消耗了14秒的時間。

而在本地使用PostgreSQL作為資料庫後端的Django ORM測試僅僅花費了3秒的時間:

使用list()對數據查詢結果進行處理是將其載入到Pandas中的一個常規前置操作,相當於遍歷查詢集的結果並將每一條數據添加到一個列表中。類似於以下操作:

res = []  for i in xx:     res.append(i) 

只是一個list()操作,就讓MongoDB的速度比PostgreSQL慢如此之多,難道我哪裡操作不對?

歡迎小夥伴們出謀劃策,分享解決方案~

萬水千山總是情,點個「收藏」行不行