一、前言:
mongodb部署在阿里雲服務器,
mongodb中collection存儲了百萬條記錄。
需求:優化查詢指定時間段內的全部數據的查詢時間,結果有百萬級別。
最初:313587條記錄耗時:114.156 s
二、通常解決方式
百度 google後,大部分解決方式是建立複合索引,鏈接以下:
解決:建立複合索引。http://virusswb.blog.51cto.com/115214/816136
可是複合索引並無解決個人問題,耗時並無減小。
因而開始如下分析:
其實經過find()查詢獲得cursor的速度很是快。
耗時發生在cursor的next()迭代過程當中:
大部分next()很快,部分next()耗時0.00099s甚至2.9840s。
cursor.next()部分速度慢的緣由:
當數據爲空後,進入cursor._refresh() 就會變慢。
cursor._refresh()部分速度慢的緣由:
-
分析完後,發現cursor._refresh 應該會按照某種算法加載剩餘部分數據或所有數據。
其實從mongodb加載數據的過程是免不了的。
因此最初的find()查詢獲得cursor,
迭代cursor.next()或list(cursor)獲得所有記錄的調用方式是沒有任何問題的。
三、針對我問題的解決方式
通常來講,你們開發環境數據庫所在服務器與本身電腦所在服務器在同一個網段;生產環境也是如此。
而個人數據庫服務器部署在阿里雲,在本身機器上訪問互聯網中一臺機器上的數據庫,並加載百萬級數據時,
網絡延遲會很慢,致使耗時比較長。
因而測試了下將代碼放到mongodb所在服務器上執行,一樣313587條記錄耗時0.84s
完美解決了問題。
四、遺留的小尾巴
將代碼放在和數據庫同一網段的服務器上執行,會優化百萬級別的查詢時間。
可是:若是查詢記錄數太大,而服務器內存不夠,服務器會out of memory,正在執行的程序會被系統kill掉。
因此:要麼加大服務器內存,要麼再來一臺和服務器同一網段的服務器,作到單機單用。
五、總結 程序員不只要學會使用API,更須要了解其餘網絡、操做系統相關的知識。 不能夠把視線拘泥於代碼層面。 加油!【完】