【问题标题】:MongoDB: why doesn't sorting by multiple keys use an index?MongoDB:为什么不按多个键排序使用索引?
【发布时间】:2012-08-22 11:55:31
【问题描述】:

问题: 我有一个非常大的集合,由字段ts 索引:(时间戳)

> db.events.ensureIndex({'ts': -1})

我想获得最后 5 个条目。令我惊讶的是,查询不使用索引,因此非常慢:

> db.events.find().sort({'ts': -1, '_id': -1}).limit(5)

但是,仅按ts 或其他字段进行排序就应该使用索引:

> db.events.find().sort({'ts': -1}).limit(5)
> db.events.find().sort({'_id': -1}).limit(5)

这是 MongoDB 中的错误吗,这确实是文档中的功能还是我做错了什么?

其他信息:

> db.events.find().sort({'ts': -1, '_id': -1}).limit(5).explain()
{
    "cursor" : "BasicCursor",
    "nscanned" : 795609,
    "nscannedObjects" : 795609,
    "n" : 5,
    "scanAndOrder" : true,
    "millis" : 22866,
    "nYields" : 73,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {

    }
}
> db.events.find().sort({'ts': -1}).limit(5).explain()
{
    "cursor" : "BtreeCursor ts_-1",
    "nscanned" : 5,
    "nscannedObjects" : 5,
    "n" : 5,
    "millis" : 0,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {
            "ts" : [
                    [
                            {
                                    "$maxElement" : 1
                            },
                            {
                                    "$minElement" : 1
                            }
                    ]
            ]
    }
}

【问题讨论】:

    标签: mongodb indexing mongodb-indexes


    【解决方案1】:

    值得阅读索引建议和常见问题 wiki 页面的 Indexing Strategies 部分。

    您可能会遗漏一些注意事项:

    • MongoDB 每次查询只使用一个索引

    • 使用的sort 列必须是索引中的最后一列

    因此,对于您的示例,您应该在 ts_id 上添加复合索引:

    db.events.ensureIndex({'ts':-1, '_id':-1});

    .. 并通过explain() 确认排序现在正在使用预期的索引:

    > db.events.find().sort({'ts': -1, '_id':-1}).limit(5).explain()
    {
        "cursor" : "BtreeCursor ts_-1__id_-1",
        "nscanned" : 5,
        "nscannedObjects" : 5,
        "n" : 5,
        "millis" : 0,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
            "ts" : [
                [
                    {
                        "$maxElement" : 1
                    },
                    {
                        "$minElement" : 1
                    }
                ]
            ],
            "_id" : [
                [
                    {
                        "$maxElement" : 1
                    },
                    {
                        "$minElement" : 1
                    }
                ]
            ]
        }
    }
    

    【讨论】:

    • 这确实是答案 - 我猜关系数据库已经宠坏了我...... :) 谢谢!
    • 为什么排序列必须是索引的最后一列?
    猜你喜欢
    • 2018-09-20
    • 2015-08-08
    • 1970-01-01
    • 2020-02-07
    • 2021-09-21
    • 2013-12-15
    • 2014-07-28
    • 2012-01-16
    • 2015-08-18
    相关资源
    最近更新 更多