我有一大堆「消息」與'到','從','類型'和'visible_to'字段,我想查詢與一個相當複雜的查詢,只拉扯消息/從一個特定該用戶可見的特定類型的用戶。下面是一個實際的例子:強制使用複雜的MongoDB查詢索引?
{
"$and": [
{
"$and": [
{
"$or": [
{
"to": "52f65f592f1d88ebcb00004f"
},
{
"from": "52f65f592f1d88ebcb00004f"
}
]
},
{
"$or": [
{
"type": "command"
},
{
"type": "image"
}
]
}
]
},
{
"$or": [
{
"public": true
},
{
"visible_to": "52f65f592f1d88ebcb00004f"
}
]
}
]
}
使用索引:
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "n2-mongodb.messages",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"expires" : 1
},
"ns" : "n2-mongodb.messages",
"name" : "expires_1",
"background" : true,
"safe" : null
},
{
"v" : 1,
"key" : {
"from" : 1
},
"ns" : "n2-mongodb.messages",
"name" : "from_1",
"background" : true,
"safe" : null
},
{
"v" : 1,
"key" : {
"type" : 1
},
"ns" : "n2-mongodb.messages",
"name" : "type_1",
"background" : true,
"safe" : null
},
{
"v" : 1,
"key" : {
"ts" : 1,
"type" : -1
},
"ns" : "n2-mongodb.messages",
"name" : "ts_1_type_-1",
"background" : true,
"safe" : null
},
{
"v" : 1,
"key" : {
"to" : 1
},
"ns" : "n2-mongodb.messages",
"name" : "to_1",
"background" : true,
"safe" : null
},
{
"v" : 1,
"key" : {
"visible_to" : 1
},
"ns" : "n2-mongodb.messages",
"name" : "visible_to_1",
"background" : true,
"safe" : null
},
{
"v" : 1,
"key" : {
"public" : 1,
"visible_to" : 1
},
"ns" : "n2-mongodb.messages",
"name" : "public_1_visible_to_1"
},
{
"v" : 1,
"key" : {
"to" : 1,
"from" : 1
},
"ns" : "n2-mongodb.messages",
"name" : "to_1_from_1"
}
]
這裏是我們的MongoDB 2.2.2實例講解(真)的輸出,它看起來像一個全掃描:
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 35702,
"nscanned" : 35702,
"nscannedObjectsAllPlans" : 35702,
"nscannedAllPlans" : 35702,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 1,
"nChunkSkips" : 0,
"millis" : 85,
"indexBounds" : {
},
"allPlans" : [
{
"cursor" : "BasicCursor",
"n" : 0,
"nscannedObjects" : 35702,
"nscanned" : 35702,
"indexBounds" : {
}
}
],
"server" : "XXXXXXXX"
}
看看解釋輸出,MongoDB沒有使用任何索引 - 有沒有辦法讓它至少使用複合索引{to:1,from:1}來顯着縮小搜索空間?或者有更好的方法來優化這個查詢嗎?或者是MongoDB完全不適合這樣的查詢?
使用'$或',每個子句都可以使用自己的索引。你可以包含這個查詢的'explain(true)'和這個集合的'db.collection.getIndexes()'的輸出嗎?在你的六個條款中,你建議的{to,from}索引只適用於一個。 – Stennie
@Stennie記住嵌套的$ ors在下一個版本之前不會有優化,他可能使用舊版本 – Sammaye
那麼你是說如果我有一個索引{to:1,from:1}和索引{public:1 ,visible_to:1}和一個索引{type:1},它會在2.4版本之後使用它們中的每一個? – outside2344