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

用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 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可能是导致内存溢出的的真凶,因为在查找之后在排序,由于数据量比较大,所以占用内存比较高,容易内存溢出。于是注释掉,在运行,发现不再报错了。




你可能感兴趣的:(MongoDB)