【MongoDB】sort stage buffered data usage of 33554446 bytes exceeds internal limit of 33554432 bytes

来源:互联网 发布:网络黑侠所有的书 编辑:程序博客网 时间:2024/05/21 11:17

用java在链接Mongo库时候做查询时候,发生了如下错误:

Exception in thread "main" com.mongodb.MongoException: Runner error: Overflow sort stage buffered data usage of 33554446 bytes exceeds internal limit of 33554432 bytes

当时用的语句是这样的:

List<InionShippingData> InionShippingList = datastore.createQuery(InionShippingData.class).order("-reDate").asList();

错误分析:是因为collection的数据量太大,MongoDB内存溢出。

解决方案:

1.优化查询和索引。 

2.减少输出列(限制输出列个数)或行(如limit函数,或限制输入查询_id数量)。 

3.将查询分2步,第1步只输出_id,第2步再通过_id查明细。

处理过程:建立索引 这边我通过客户端给这个表建立了一个索引

db.getCollection('InionShippingData').ensureIndex( { "epc" : 1 , "sscc" : 1 } );

再次执行这段代码,不起作用。还是报错。删除索引。

db.getCollection('InionShippingData').dropIndex( { "epc" : 1, "sscc" : 1 } );

网上找的方法: 增加缓存的值,但注意,这个参数只能在3.0后的版本使用。 如果因为这个用户把整个db的默认缓存增加,那服务器的可用内存就减少,性能就减少,在经济效益上,为了解决这个用户问题而增加缓存不合算,两者只能权衡,每种方案都有利弊。

> use admin  switched to db admin  > db.runCommand( { getParameter : 1, "internalQueryExecMaxBlockingSortBytes" : 1 } ){ "internalQueryExecMaxBlockingSortBytes" : 33554432, "ok" : 1 }  >  db.adminCommand({setParameter: 1,internalQueryExecMaxBlockingSortBytes:50151432}){ "was" : 33554432, "ok" : 1 }  我这边本地实验> use udid  switched to db udid  > db.runCommand( { getParameter : 1, "internalQueryExecMaxBlockingSortBytes" : 1 } ){    "ok" : 0.0,    "errmsg" : "getParameter may only be run against the admin database.",    "code" : 13}

继续寻找方案:决定暂时采用分页处理。

DBCursor dbCursor = datastore.getDB().getCollection("InionShippingData").find().sort(new BasicDBObject("reDate", 1)).skip(i).batchSize(10000);

运行后发现依然报错。

这时候我注意到 sort可能是导致内存溢出的的真凶,因为在查找之后在排序,由于数据量比较大,所以占用内存比较高,容易内存溢出。于是注释掉,在运行,发现不再报错了。




阅读全文
0 0
原创粉丝点击