【发布时间】:2013-12-27 17:43:33
【问题描述】:
分析慢查询我发现了一些非常奇怪的事情:对于以下操作,即使查询参数 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"
}
在一些没有结果的谷歌搜索之后,我发现省略了 "$orderby": { "$natural" : 1} 查询非常快,只扫描了 7 个文档而不是 33061。所以我假设在我的情况下使用 $orderby 确实避免使用索引家庭编号。奇怪的是,结果的顺序在任何一种情况下都没有不同。据我了解 $natural 顺序重复使用 "$orderby": { "$natural" : 1} 或没有明确的顺序。另一个非常有趣的观察是,这个问题不会出现在 capped collection 上!!
这个问题产生以下问题:
- 如果不使用任何排序/排序,生成的订单不应该是磁盘上的订单,即
$naturalorder? - 我能否创建一个(复合)索引以用于自然排序?
- 如何在不严重损失性能的情况下反转使用索引的简单查询的顺序而不进行排序?
- 在使用查询参数和 orderby 时,幕后会发生什么?为什么这不会发生在有上限的集合上?我想了解这种奇怪的行为。
- 上述问题的答案是否与您是否使用分片/复制无关?对多个分片进行查询的自然顺序是什么?
注意我使用的是 MongoDB 2.2。有一张与此问题相关的票:https://jira.mongodb.org/browse/SERVER-5672。虽然在那张票中似乎问题也出现在有上限的集合中,但我无法确认(可能是由于不同的 mongo 版本)。
【问题讨论】:
标签: mongodb sorting indexing query-performance