2011-12-09 73 views
12

我有这些指标的集合:mongodb在排序时不使用索引?

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

> 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排序时

mongodb不再使用索引:

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

任何解决方案?

回答

32

Mongo实际上使用一个索引(你可以通过在说明中看到BtreeCursor来判断),而不是复合索引。

重要的是要记住,当你有复合指数时,方向很重要。

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

蒙戈选择使用反向MSG_ID指数在你的例子,因为它更快地检索有序的结果,然后匹配O(n)的时间,而不是那种在匹配结果,然后O(nlogn)时间。

+2

+1优秀的答案! – Petrogad

+0

谢谢你,先生! –

+1

加入反向索引确实有帮助。谢谢。 – Bearice

1

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

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

欲了解更多详情,请参阅http://www.mongodb.org/display/DOCS/Query+Optimizer