分析慢查询我发现了一些非常奇怪的事情:对于以下操作,即使查询参数family_id上有索引,也会扫描整个集合(33061文档):
{
"ts" : ISODate("2013-11-27T10:20:26.103Z"),
"op" : "query",
"ns" : "mydb.zones",
"query" : {
"$query" : {
"family_id" : ObjectId("52812295ea84d249934f3d12")
},
"$orderby" : {
"$natural" : 1
}
},
"ntoreturn" : 20,
"ntoskip" : 0,
"nscanned" : 33061,
"keyUpdates" : 0,
"numYield" : 91,
"lockStats" : {
"timeLockedMicros" : {
"r" : NumberLong(83271),
"w" : NumberLong(0)
},
"timeAcquiringMicros" : {
"r" : NumberLong(388988),
"w" : NumberLong(22362)
}
},
"nreturned" : 7,
"responseLength" : 2863,
"millis" : 393,
"client" : "127.0.0.1",
"user" : "mydb"
}
在没有结果的Google搜索之后,我发现忽略"$orderby": { "$natural" : 1}
查询非常快,只扫描了7个文档而不是33061.所以我假设在我的情况下使用$orderby
会避免在family_id上使用索引。奇怪的是,在任何一种情况下,结果顺序都没有区别。据我了解$自然顺序,使用"$orderby": { "$natural" : 1}
或没有明确的顺序是同义的。另一个非常有趣的观察是,这个问题不会出现在上限集合上!!
此问题产生了以下问题:
$natural
订单?注意我使用的是MongoDB 2.2。有一个与此问题相关的故障单:https://jira.mongodb.org/browse/SERVER-5672。虽然在票证中似乎也出现了问题,但我无法确认(可能是因为mongo版本不同)。
答案 0 :(得分:1)
据我了解$自然顺序,它是重复使用的 “$ orderby”:{“$ natural”:1}或没有明确的订单。
这是$自然顺序的错误描述。 MongoDB以磁盘上的某种顺序存储记录,并通过双向链表跟踪它们。 $ natural order是您遍历链表时获得的顺序。但是,如果您执行 not 指定$ natural,那么 将始终获得 - 不是随机顺序,不是插入顺序,不是物理磁盘顺序,而是“逻辑”磁盘order - 遍历链表时它们出现的顺序。
如果不使用任何排序/排序,则不应该生成订单 磁盘上的订单,即$ natural order?
是的,假设你明白“磁盘订单”不是严格的物理订单,它的顺序是它们在链接的记录列表中。
我可以创建一个自然排序的(化合物)索引吗?
我不清楚你的意思是自然排序 - 如果你在查询期间使用索引,那么文档将按索引顺序遍历,而不是以$自然顺序遍历。
如何在不产生严重性能损失的情况下,反转使用索引而不进行排序的简单查询的顺序?
您不能 - 如果您正在使用索引,那么您将按索引顺序获取记录 - 您的选项是按顺序获取它们,与该顺序相反或创建复合索引,您可以按字段索引搜索您想要排序的和字段。
使用查询参数和orderby后幕后会发生什么?为什么这不会发生在上限集合中?我想了解这种奇怪的行为。
发生什么取决于可用的索引,但查询优化器尝试使用有助于过滤和排序的索引 - 如果不可能,它将选择具有最佳实际性能的索引。
上述问题的答案是否与您是否使用无关 是否分片/复制?查询的自然顺序是什么? 多个分片?
这是来自每个单独碎片的$ natural命令的一些非确定性合并。