14

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

> 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,
...
}

任何解决方案?

4

2 回答 2

33

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

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

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

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

于 2011-12-09T03:38:25.200 回答
1

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

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

有关更多详细信息,请参阅http://www.mongodb.org/display/DOCS/Query+Optimizer

于 2011-12-09T03:37:16.703 回答