3

问题: 我有一个按字段索引的非常大的集合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
                            }
                    ]
            ]
    }
}
4

1 回答 1

5

值得一读 Indexing Advice & FAQ wiki 页面的Indexing Strategies部分。

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

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

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

ts因此,对于您的示例,您应该在and上添加一个复合索引_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
                }
            ]
        ]
    }
}
于 2012-08-22T12:23:21.197 回答