Mongodb數據庫Query failed with error code 96 and error message 'Executor error during find command

mongodb在查詢集合時,數據量特別大時,報以下錯誤

Query failed with error code 96 and error message 'Executor error during find command: OperationFailed: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.' on server 127.0.0.1:27017

Dao的方法:

public static List<Document> list(Bson filters, int limit, int offset) {
        filters =
                Filters.and(filters, Filters.gt(Constants.FIELD_STATUS, Constants.STATUS_DELETED));
       FindIterable<Document> fi =dbCollection.find(filters).sort(Sorts.descending(Constants.UPDATED_AT));
        List<Document> list =(limit > 0 ? fi.skip(offset).limit(limit) : fi).into(new ArrayList<Document>());
        return ApplicationHelper.id2String(list);
    }

我在查詢集合列表時,添加了排序字段,按最後修改時間排序。從報錯信息字面意思來看

Sort operation used more than the maximum 33554432 bytes of RAM.,33554432 bytes算下來正好是32Mb,而mongodb的sort操作是把數據拿到內存中再進行排序的,爲了節約內存,默認給sort操作限制了最大內存爲32Mb,當數據量越來越大直到超過32Mb的時候就自然拋出異常了!

所以解決方案有兩個思路,

一個是既然內存不夠用那就修改默認配置多分配點內存空間;

一個是像錯誤提示裏面說的那樣創建索引。
首先說如何修改默認內存配置,在Mongodb命令行窗口中執行如下命令即可:
 

db.adminCommand({setParameter:1, internalQueryExecMaxBlockingSortBytes:335544320}) //不推薦使用

這樣直接把內存擴大了10倍,變成了320Mb。除非你服務器的內存足夠大,否則sort佔用的內存會成爲一個嚴重的資源消耗!

接下來,第二種方法就是是創建索引,也比較簡單

db.yourCollection.createIndex({<field>:<1 or -1>})  //只執行這句就能解決bug  注意不能直接複製粘貼,要根據集合編寫語句。

 

具體要對哪個字段加索引,可根據需求自己定義,其中1表示升序排列,-1表示降序排列。索引創建之後即時生效,不需要重啓數據庫和服務器程序,也不需要對原來的數據庫查詢語句進行修改。創建索引的話也有不好的地方,會導致數據寫入變慢,同時Mongodb數據本身佔用的存儲空間也會變多。不過從查詢性能和服務器資源消耗這兩方面來看,通過創建索引來解決這個問題還是最佳的方案!

如果對索引還在不太清楚的地方,可以參考這篇mongodb索引,寫的比較淺顯,可做參考

https://blog.csdn.net/weixin_33446857/article/details/83085018
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章