Mongodb Sort Operations

问题

执行以下查询出错:"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.",

db.getCollection('notice')
.find({ "field1" : aaa})
.sort({"sortField1" : -1, "sortField2" : -1})

原因:

mongodb在执行排序时,首先尝试使用索引中的指定顺序检索文档,如果没有可用索引,则会将所有文档加载到内存中排序,默认情况下,可用内存的配置为32M,超过该值时就会遇到以上错误;

使用如下命令可以查看该配置:

// 注意,在admim集合中执行
db.runCommand( { getParameter : 1, "internalQueryExecMaxBlockingSortBytes" : 1 } )

解决方法:

1,既然首先查找索引,那么性能最友好的方式便是在排序字段上加索引;

// 创建索引 createIndex
db.getCollection('notice').createIndex( { 'sortField': 1 } )
// 推荐用 ensureIndex
db.getCollection('notice').ensureIndex( { 'sortField': 1 } )

2,也可修改配置,提高可用内存;

db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes: 335544320})

3,使用聚合命令排序,聚合命令具有最大的内存使用配置,在处理大型数据集时,可以添加{ allowDiskUse: true}的option,将中间处理过程输出到磁盘临时文件进行处理,当然这个性能会差

db.getCollection('notice').aggregate( [
      { $sort : { 'sortField': 1} }
   ],
   { allowDiskUse: true }
)

其他知识点:

Sort Operations

  https://docs.mongodb.com/manual/reference/limits/#Sort-Operations

Sort and Index Use

  https://docs.mongodb.com/manual/reference/method/cursor.sort/#sort-index-use

    MongoDB可以从包含排序字段的索引中获得排序操作的结果。如果排序使用与查询谓词相同的索引,则MongoDB可以使用多个索引来支持排序操作。

    如果MongoDB无法使用一个或多个索引来获取排序顺序,则MongoDB必须对数据执行阻塞排序操作。阻塞排序表示MongoDB必须使用并处理所有输入文档,直到返回结果。阻塞排序不会阻塞集合或数据库上的并发操作。

   

原文地址:https://www.cnblogs.com/petunsecn/p/14325757.html