12

我有一个 mongodb 集合,“功能”,有 3 个字段:名称、活动、重量。我将按权重降序对特征进行排序:

db.features.find({active:true},{name:1, weight:1}).sort({weight:-1})

为了优化,我为它创建索引:

db.features.ensureIndex({'active': 1, 'weight': -1})

explain()我可以看到它在查询中使用时效果很好。

但是,当我通过权重升序查询它时,我想我刚刚创建的索引将不起作用,我需要创建另一个权重升序索引。询问:

db.features.find({active:true},{name:1, weight:1}).sort({weight:1}).explain()

当我使用 explain() 显示索引如何工作时,我发现它打印出来:

"cursor" : "BtreeCursor active_1_weight_-1 reverse",

索引反向是否意味着查询已被索引优化?

一般来说,如果我将按重量在某些情况下升序和在其他情况下降序对它进行排序,我是否需要创建 2 个索引,例如按重量升序和按重量降序?

4

4 回答 4

13

我知道我迟到了,但我想补充一点细节。当您使用 explain() 并输出 cursor: BtreeCursor 时,它并不总是保证仅使用索引来满足您的查询。您还必须检查 explain() 结果中的“indexOnly”选项。如果 indexOnly 输出为 true,则表示仅使用索引就可以满足您的查询,并且根本没有引用集合中的文档。这称为“覆盖索引查询” http://docs.mongodb.org/manual/applications/indexes/

但是如果explain的结果是cursor:BtreeCursor和indexOnly:false,则说明除了使用索引之外,还引用了集合。在您的情况下,对于查询:

    db.features.find({active:true},{name:1, weight:1}).sort({weight:1}).explain()

Mongo 会使用索引 'active': 1, 'weight': -1 来满足查询的初始部分,即 db.features.find({active:true}) 并且会在不使用索引的情况下完成排序。因此,要准确了解,您必须查看 explain() 中的 indexOnly 结果。

于 2013-02-16T15:13:16.190 回答
9

从本文档可以看出,当explain()输出时BtreeCursor,表示使用了索引。使用索引时,会设置 indexBounds 以指示在索引中扫描的键边界。但是,如果 putput 显示BasicCursor,则表示表扫描样式操作。

因此,根据您所说的,从explain()结果中,您可以看到您在BTree Cursor名为的索引上使用了 a ,active_1_weight_-1并且reverse意味着您正在以相反的顺序迭代索引。

所以不,您不需要创建单独的索引。

于 2012-08-23T08:40:20.200 回答
3

这很令人困惑。在 mongodb 类中有一个示例,请参见下文。

注意 BtreeCursor reverse 仅用于在跳过和限制命令中进行排序

不是为了查找记录。

教训是如果 nscan =40k 并且 n=10 意味着 btree 索引不用于定位记录。

因此,当您看到 btreecursor 索引反向时,并不一定意味着索引习惯于定位 reocrd。

假设您有一个名为 tweets 的集合,其文档包含有关推文时间的created_at 和用户发布推文时的followers_count 的信息。您可以从以下解释输出中推断出什么?db.tweets.find({"user.followers_count":{$gt:1000}}).sort({"created_at" : 1 }).limit(10).skip(5000).explain() { "cursor" :“BtreeCursor created_at_-1 reverse”,“isMultiKey”:假,“n”:10,“nscannedObjects”:46462,“nscanned”:46462,“nscannedObjectsAllPlans”:49763,“nscannedAllPlans”:49763,“scanAndOrder”:假,“indexOnly”:假,“nYields”:0,“nChunkSkips”:0,“millis”:205,“indexBounds”:{“created_at”:[[{“$minElement”:1},{“$maxElement”:1}]]},“server”:“localhost.localdomain:27017”}此查询执行集合扫描。yes 查询使用索引来确定返回结果文档的顺序。yes 查询使用索引来确定哪些文档匹配。否 查询返回 46462 个文档 否 { "$maxElement" : 1 } ] ] }, "server" : "localhost.localdomain:27017" } 此查询执行集合扫描。yes 查询使用索引来确定返回结果文档的顺序。yes 查询使用索引来确定哪些文档匹配。否 查询返回 46462 个文档 否 { "$maxElement" : 1 } ] ] }, "server" : "localhost.localdomain:27017" } 此查询执行集合扫描。yes 查询使用索引来确定返回结果文档的顺序。yes 查询使用索引来确定哪些文档匹配。否 查询返回 46462 个文档 否 yes 查询使用索引来确定返回结果文档的顺序。yes 查询使用索引来确定哪些文档匹配。否 查询返回 46462 个文档 否 yes 查询使用索引来确定返回结果文档的顺序。yes 查询使用索引来确定哪些文档匹配。否 查询返回 46462 个文档 否

于 2014-10-02T02:51:02.403 回答
1

假设您使用的是 2.0+,那么反向遍历对 MongoDB 来说成本并不高,因此对于这种情况,您不需要为正向/反向排序创建单独的索引。如果您愿意,可以通过创建它并使用hint()来确认(优化器将缓存当前索引一段时间,因此不会自动选择其他索引)。

于 2012-08-23T08:34:09.233 回答