2011-12-09 118 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