溢出排序阶段缓冲数据使用超出内部限制

时间:2014-11-19 17:52:51

标签: mongodb mongodb-query mongodb-indexes

使用代码:

all_reviews = db_handle.find().sort('reviewDate', pymongo.ASCENDING)
print all_reviews.count()

print all_reviews[0]
print all_reviews[2000000]

计数打印2043484,并打印all_reviews[0]

然而,当打印all_reviews[2000000]时,我收到错误:

  

pymongo.errors.OperationFailure:数据库错误:运行程序错误:溢出排序阶段缓冲数据使用量33554495字节超出内部限制33554432字节

我该如何处理?

6 个答案:

答案 0 :(得分:106)

您在内存中排序时遇到32MB限制:

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

向排序字段添加索引。这允许MongoDB按排序顺序将文档流式传输给您,而不是尝试将它们全部加载到服务器上的内存中,并在将它们发送到客户端之前将它们排序到内存中。

答案 1 :(得分:38)

正如评论部分kumar_harsh所述,我想补充一点。

您可以使用以下admin数据库命令查看当前缓冲区使用情况:

> use admin
switched to db admin
> db.runCommand( { getParameter : 1, "internalQueryExecMaxBlockingSortBytes" : 1 } )
{ "internalQueryExecMaxBlockingSortBytes" : 33554432, "ok" : 1 }

它的默认值 32 MB(33554432字节)。在这种情况下,您运行的缓冲区数据不足,因此您可以使用自己定义的最佳值增加缓冲区限制,例如50 MB如下:

>  db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes:50151432})
{ "was" : 33554432, "ok" : 1 }

我们还可以通过mongodb配置文件中的以下参数永久设置此限制:

setParameter=internalQueryExecMaxBlockingSortBytes=309715200

希望这有帮助!!!

Note:此命令仅在版本3.0 +

之后支持

答案 2 :(得分:18)

通过索引解决

db_handle.ensure_index([("reviewDate", pymongo.ASCENDING)])

答案 3 :(得分:9)

如果您想避免创建索引(例如,您只想快速检查数据),可以使用磁盘使用聚合:

all_reviews = db_handle.aggregate([{$sort: {'reviewDate': 1}}], {allowDiskUse: true})

(不知道如何在pymongo中这样做。)

答案 4 :(得分:3)

索引的JavaScript API语法:

if (!Intl) {
  // eslint-disable-next-line global-require no-global-assign
  Intl = require('intl')
}

答案 5 :(得分:1)

就我而言,有必要在代码中修复nessary索引并重新创建它们:

rake db:mongoid:create_indexes RAILS_ENV=production

当存在所需的字段索引时,不会发生内存溢出。

PS 在此之前,我必须在创建长索引时禁用错误:

# mongo
MongoDB shell version: 2.6.12
connecting to: test
> db.getSiblingDB('admin').runCommand( { setParameter: 1, failIndexKeyTooLong: false } )

也可能需要reIndex

# mongo
MongoDB shell version: 2.6.12
connecting to: test
> use your_db
switched to db your_db
> db.getCollectionNames().forEach( function(collection){ db[collection].reIndex() } )