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
 

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