【问题标题】:mongodb not using indexes when sorting?排序时mongodb不使用索引?
【发布时间】:2012-01-16 11:05:47
【问题描述】:

我有一个包含这些索引的集合:

> db.message.getIndexKeys()
[
    {
        "_id" : 1
    },
    {
        "msgid" : 1
    },
    {
        "keywords" : 1,
        "msgid" : 1
    }
]

和类似的查询

db.message.find({'keywords': {'$all': ['apple', 'banana']}}).limit(30).explain()

与索引配合得很好

{
    "cursor" : "BtreeCursor keywords_1_msgid_1",    
    "nscanned" : 96,
    "nscannedObjects" : 96,
    ...
}

但是当使用 msgid 排序时:

db.message.find({'keywords': {'$all': ['apple', 'banana']}})
    .sort({msgid:-1})
    .limit(30).explain()

mongodb 不再使用索引:

{
"cursor" : "BtreeCursor msgid_1 reverse",
"nscanned" : 1784455,
"nscannedObjects" : 1784455,
...
}

有什么解决办法吗?

【问题讨论】:

    标签: mongodb mongodb-indexes nosql


    【解决方案1】:

    Mongo 实际上使用索引(您可以通过在解释中看到 BtreeCursor 来判断),而不是复合索引。

    重要的是要记住,当您有复合索引时,方向很重要。

    试试:db.ensureIndex({ keywords: 1, msg_id: -1 })

    Mongo 在您的示例中选择反向使用 msg_id 索引,因为以排序顺序检索结果然后在 O(n) 时间内匹配比匹配结果然后在 O(nlogn) 时间内排序更快。

    【讨论】:

      【解决方案2】:

      它正在使用一个索引——msgid 上的索引。 MongoDB 通过尝试所有可能的索引并使用先完成的索引来选择用于查询的索引。此结果将被缓存以供 1,000 次查询使用,或者直到对集合进行一定数量的修改(数据更改、新索引等)。

      您可以通过将true 传递给explain() 来查看所有尝试过的查询计划。

      更多详情请见http://www.mongodb.org/display/DOCS/Query+Optimizer

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-07
        • 1970-01-01
        • 1970-01-01
        • 2020-04-19
        • 2019-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多