MongoDB降序升序索引

4

我正在学习mongodb索引,想要问一个问题。我已经阅读了有关mongodb索引的文档,但是我不理解其中的一件事。

我创建了一个

索引price(-1)

如果我使用

排序price(1)

这个排序会使用索引吗?

3个回答

7
是的,MongoDB可以从两个方向扫描索引,因此你的索引顺序并不重要。这仅在您有一个复合索引(具有多个字段)时才重要,在该情况下,您仍然可以从第一个字段的两端开始索引扫描,但下一个字段由您给出的顺序固定。
尽管如此,MongoDB也可以沿着索引按任意方向遍历。因此,对于单字段索引,升序和降序索引是可以互换的。但对于复合索引则不是这样:在复合索引中,排序顺序的方向可能会对结果产生更大的影响。
引用自MongoDB文档

1
答案是是。
rs0:PRIMARY> db.bill.save({price: 100})
rs0:PRIMARY> db.bill.save({price: 110})
rs0:PRIMARY> db.bill.save({price: 120})
rs0:PRIMARY> db.bill.save({price: 130})
rs0:PRIMARY> db.bill.save({price: 140})
rs0:PRIMARY> db.bill.save({price: 150})
rs0:PRIMARY> db.bill.encureIndex({price:-1})
rs0:PRIMARY> db.bill.find().sort({price:1}).explain()
{
"cursor" : "BtreeCursor price_-1 reverse",
"isMultiKey" : false,
"n" : 6,
"nscannedObjects" : 6,
"nscanned" : 6,
"nscannedObjectsAllPlans" : 6,
"nscannedAllPlans" : 6,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 18,
"indexBounds" : {
    "price" : [
        [
            {
                "$minElement" : 1
            },
            {
                "$maxElement" : 1
            }
        ]
    ]
},
"server" : "localhost:27017"
}
rs0:PRIMARY> db.bill.find().sort({price:-1}).explain()
{
"cursor" : "BtreeCursor price_-1",
"isMultiKey" : false,
"n" : 6,
"nscannedObjects" : 6,
"nscanned" : 6,
"nscannedObjectsAllPlans" : 6,
"nscannedAllPlans" : 6,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
    "price" : [
        [
            {
                "$maxElement" : 1
            },
            {
                "$minElement" : 1
            }
        ]
    ]
},
"server" : "localhost:27017"
}

注意游标是:“BtreeCursor price_-1 reverse”和“BtreeCursor price_-1”。Mongodb会自动使用“反向索引”。

1
首先,当你第一次学习索引时,提出这个问题是很好的。回答你的问题,基本上是开发人员的职责使用索引以增加查询性能。在你的情况下,不应该使用导致性能下降的索引。在应用索引之前了解查询模式,并根据需要应用索引。
MongoDB中还有一个内置的查询优化器,它是经验性的。现在它的工作方式是,在并行测试查询计划时,尝试多个计划,并记录完成最快的计划。如果计划的性能随时间改变,例如随着数据的变化,数据库将重新优化(即重试所有可能的计划)。
你也可以自己优化查询。为了测试你所使用的查询计划,你可以在查询后使用explain()。
   db.collection.find({}).sort({price:1}).explain()

结果为---
 {
   "cursor": "BtreeCursor x_1",
   ...
   "nscanned": 100
   ....

 }

使用索引的查询计划具有游标类型BtreeCursor。如果查询计划不使用索引,则游标类型为BasicCursor。

链接:http://docs.mongodb.org/manual/core/query-optimization/


你不需要使用hint()来提示查询规划器反向遍历索引(如果适用),并且你只能使用现有的索引规范或名称进行提示。如果你只有一个基于{price:1}的索引,那么在{price:-1}上的提示应该会失败并抛出“坏提示”异常。通常情况下,你应该非常谨慎地使用hint()。强制使用特定的索引通常会降低性能;最好了解为什么给定查询形状没有使用预期的索引。 - Stennie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接