MongoDB分页获取数据排序阶段缓存溢出问题
2019-10-12 本文已影响0人
缄默_8421
问题描述:
MongoDB上按某字段进行分页排序查询,发现使用skip()方法跳过较大规模的数据时报错,无法得到查询结果。
一、错误再现
查询语法如下:
db.getCollection("log_collection").find().sort({
"createTime": -1
}).limit(20).skip(85100)
报错信息如下:
[Error] Executor error during find command :: caused by :: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.
at line 0, column 0, Time: 0.173000s
二、问题原因
正如错误提示所说,即 MongoDB 排序阶段缓冲数据使用超出内部限制。
三、解决方案
1、 扩大排序内存的限制,例如扩大10倍至320M。如:
db.adminCommand({setParameter:1, internalQueryExecMaxBlockingSortBytes:335544320})
2、 给排序字段加索引。如:
db.getCollection("log_collection").createIndex({“createTime” : <1 or -1> })
3、 在执行一个更大规模排序时,即使已经加了索引依然超过限制,可以使用aggregate()方法的 allowDiskUse 参数设置将数据写到临时文件进行排序。如:
//语法:pipeline -> array, options -> document
db.collection.aggregate(pipeline, options)
//举例:
db.getCollection("log_collection").aggregate(
[
{$sort : {"createTime" : -1}}
],
{allowDiskUse: true}
);
四、总结与思考
使用方案3基本上能解决溢出的问题,但在数据规模异常庞大(TB、PB级)这种方案的有效性、适用性和实用性有待考证,是否可以考虑在 MongoDB 上“分库分表”,减少单集合的文档数量,或者选用其他 NoSQL 数据库?