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

she*_*158 77 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]
Run Code Online (Sandbox Code Playgroud)

计数打印2043484,然后打印all_reviews[0].

但是在打印时all_reviews[2000000],我收到错误:

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

我该如何处理?

A. *_*vis 112

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

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

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

  • 实际上,它可以改变.您需要运行此命令:`db.adminCommand({setParameter:1,internalQueryExecMaxBlockingSortBytes:<limit in bytes>})`.资料来源:http://askubuntu.com/questions/501937/how-to-increase-buffered-data-limit (28认同)
  • 最好声明一个索引,这样你就不需要在RAM中进行排序:更快,更可靠,有限的RAM使用而不是可能无限制.如果你坚持,将你的"查找"变成一个聚合(可以使用100MB的RAM进行排序),并设置allowDiskUse:true,告诉聚合框架如果超过100MB的RAM就溢出到磁盘.与宣布适当的指数相比,预计会造成严重的性能损失.http://docs.mongodb.org/manual/reference/operator/aggregation/sort/#sort-memory-limit (7认同)
  • 如果这是接受的答案,那么它应该包括有关如何添加索引的信息. (6认同)
  • 值得注意的是,对于mongoose用户来说,在模式中的prop上设置索引:true将解决这个问题... mongoose将遍历所有模式并确保在启动应用程序之前字段实际上是索引...这是除非你使用mySchema.set('autoIndex',false)关闭此行为; (3认同)
  • 我已经在排序字段上创建了一个索引,但它仍然给我这个"排序操作使用超过最大33554432字节的RAM"错误可能是因为我在排序之前应用匹配操作并且根据mongo doc如果你在排序之前使用匹配操作它将忽略索引并在内存中对所有匹配的记录进行排序. (2认同)

JER*_*RRY 41

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

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

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

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

>  db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes:50151432})
{ "was" : 33554432, "ok" : 1 }
Run Code Online (Sandbox Code Playgroud)

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

setParameter=internalQueryExecMaxBlockingSortBytes=309715200
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助 !!!

Note:此命令仅在3.0 +版之后支持


she*_*158 19

用索引解决了

db_handle.ensure_index([("reviewDate", pymongo.ASCENDING)])
Run Code Online (Sandbox Code Playgroud)


por*_*szd 11

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

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

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