我有一个代码,可以进行一个相当简单的查询跳过限制排序。 我遇到了一个很难解释的现象。在
关于“小”跳过值-一切都很好。 在“高”跳过值(>;18000)-如果没有以下错误,我无法获得限制高于20的结果:
OperationFailure: Executor error during find command: OperationFailed: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.
问题是-为什么只有大量的跳跃才会发生这种情况?我怎么解决这个问题?在
在mongoShell上运行它(即使DBQuery.shellBatchSize=300)工程。 它似乎在使用索引 我的收藏.find({'foo':false})。跳过(19000)。限制(100)。排序({'meta_数据创建于':-1}).explain()
^{pr2}$}
更多信息: 似乎排序确实是在内存中完成的——它存在于被拒绝的计划中。 那么我们能做些什么呢?在
"rejectedPlans" : [
{
"stage" : "SKIP",
"skipAmount" : 19000,
"inputStage" : {
"stage" : "SORT",
"sortPattern" : {
"meta_data.created_at" : -1
},
"limitAmount" : 19100,
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"foo" : 1,
"_id" : 1
},
"indexName" : "foo_1__id_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"foo" : [
"[false, false]"
],
"_id" : [
"[MinKey, MaxKey]"
]
}
}
}
}
}
}
还有一个问题。为什么它只发生在一个大的跳跃数?为什么重要?在
这是因为这种情况发生在记忆中。提供sort and limit时,必须在内存中维护的文档数等于limit。当有跳过和限制时,存储在内存中的数字必须是“跳过+限制”。在
您可以确保有一个索引支持排序和筛选器,如果有一个索引但没有被选中,您可以使用hint来指定查询应该使用哪个索引。在
“最佳”计划是在您第一次运行特定查询时选择的,该查询将在将来被缓存(记住)。当跳数足够大时,最好的计划可能在小数目下运行良好,不再是最好的。在
相关问题 更多 >
编程相关推荐