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 数据库?

上一篇 下一篇

猜你喜欢

热点阅读