MongoDB 效能優化之分頁查詢
阿新 • • 發佈:2018-12-24
最常見的分頁採用的是skip+limit這種組合方式,這種方式對付小資料倒也可以,但是對付上幾百上千萬的大資料,只能力不從心。通過如下思路改善,可以大大提高查詢速度:條件查詢+排序+限制返回記錄。邊查詢,邊排序,排序之後,抽取第一次分頁中的最後一條記錄,作為第二次分頁的條件,進行條件查詢,以此類推....
下面通過一個例子演示一下:
1.準備資料
>for(var i = 0 ;i < 2000000;i++){db.user.save({"index":i,"name":"zhangsan"+i,"age":(i+10)%100});}
>db.user.count();
2.採用skip+limit方式查詢
查詢以zhangsan2開頭的,並按照index倒敘的第100~109條資料
可以看到查詢一次需要2223ms。 3.查詢下一頁優化處理 當時使用上面方法,查詢110~119條時,依舊耗時2530ms> db.user.find({name:/^zhangsan2/}).sort({"index":-1}).skip(100).limit(10).explain(); { "cursor" : "BasicCursor", "isMultiKey" : false, "n" : 10, "nscannedObjects" : 2000000, "nscanned" : 2000000, "nscannedObjectsAllPlans" : 2000000, "nscannedAllPlans" : 2000000, "scanAndOrder" : true, "indexOnly" : false, "nYields" : 3, "nChunkSkips" : 0, "millis" : 2223, "indexBounds" : { }, "server" : "100.205:27017" }
下面我們通過程式改善一下上面下一頁的查詢,根據第一次100查詢,我們知道index的最小值為299890,由於是按照index的倒敘查詢,所以下一頁的資料為index小於299890的後續10條,查詢如下:> db.user.find({name:/^zhangsan2/}).sort({"index":-1}).skip(110).limit(10).explain(); { "cursor" : "BasicCursor", "isMultiKey" : false, "n" : 10, "nscannedObjects" : 2000000, "nscanned" : 2000000, "nscannedObjectsAllPlans" : 2000000, "nscannedAllPlans" : 2000000, "scanAndOrder" : true, "indexOnly" : false, "nYields" : 3, "nChunkSkips" : 0, "millis" : 2530, "indexBounds" : { }, "server" : "100.205:27017" }
比較一下與上面的查詢下一頁的效率有顯著的提高,當資料越大的情況下,效果會更明顯。 參考文章:> db.user.find({name:/^zhangsan2/,index:{"$lt":299890}}).sort({"index":-1}).limit(10).explain(); { "cursor" : "BasicCursor", "isMultiKey" : false, "n" : 10, "nscannedObjects" : 2000000, "nscanned" : 2000000, "nscannedObjectsAllPlans" : 2000000, "nscannedAllPlans" : 2000000, "scanAndOrder" : true, "indexOnly" : false, "nYields" : 1, "nChunkSkips" : 0, "millis" : 1523, "indexBounds" : { }, "server" : "100.205:27017" }