我在MongoDB 3.2中做了幾個「覆蓋查詢」測試,注意到它不包含一個包含$or
表達式的查詢(只在同一個字段上?)。但是,如果在同一個查詢中用$or
表達式代替$in
表達式,則它工作得很好。
我用於測試的指數如下:
db.test_collection.createIndex({ a: 1, b: 1, c: 1 });
這是$or
查詢不是通過索引
db.test_collection.find({
a: "string",
$or: [
{ b: true },
{ b: false },
],
c: "string"
}, { a: 1, b: 1, c: 1, _id: 0 });
覆蓋,這是$in
查詢is covered
db.test_collection.find({
a: "string",
b: { $in: [ true, false ] },
c: "string"
}, { a: 1, b: 1, c: 1, _id: 0 });
字段是相同的,投影是相同的。那麼,爲什麼索引不能覆蓋$or
查詢?
這是explain()
輸出爲$or
查詢:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.test_collection",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"$or" : [
{
"b" : {
"$eq" : true
}
},
{
"b" : {
"$eq" : false
}
}
]
},
{
"a" : {
"$eq" : "string"
}
},
{
"c" : {
"$eq" : "string"
}
}
]
},
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"a" : 1,
"b" : 1,
"c" : 1,
"_id" : 0
},
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"$or" : [
{
"b" : {
"$eq" : true
}
},
{
"b" : {
"$eq" : false
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"a" : 1,
"b" : 1,
"c" : 1
},
"indexName" : "a_1_b_1_c_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"a" : [
"[\"string\", \"string\"]"
],
"b" : [
"[MinKey, MaxKey]"
],
"c" : [
"[\"string\", \"string\"]"
]
}
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 2,
"executionTimeMillis" : 9,
"totalKeysExamined" : 2,
"totalDocsExamined" : 2,
"executionStages" : {
"stage" : "PROJECTION",
"nReturned" : 2,
"executionTimeMillisEstimate" : 10,
"works" : 3,
"advanced" : 2,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"transformBy" : {
"a" : 1,
"b" : 1,
"c" : 1,
"_id" : 0
},
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"$or" : [
{
"b" : {
"$eq" : true
}
},
{
"b" : {
"$eq" : false
}
}
]
},
"nReturned" : 2,
"executionTimeMillisEstimate" : 10,
"works" : 3,
"advanced" : 2,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 2,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 2,
"executionTimeMillisEstimate" : 10,
"works" : 3,
"advanced" : 2,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"a" : 1,
"b" : 1,
"c" : 1
},
"indexName" : "a_1_b_1_c_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"a" : [
"[\"string\", \"string\"]"
],
"b" : [
"[MinKey, MaxKey]"
],
"c" : [
"[\"string\", \"string\"]"
]
},
"keysExamined" : 2,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
},
"serverInfo" : {
"host" : "VM-TOMLIN-HP",
"port" : 27017,
"version" : "3.2.6",
"gitVersion" : "05552b562c7a0b3143a729aaa0838e558dc49b25"
},
"ok" : 1
}
,這是explain()
輸出爲$in
查詢:由於的方式
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.test_collection",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"a" : {
"$eq" : "string"
}
},
{
"c" : {
"$eq" : "string"
}
},
{
"b" : {
"$in" : [
false,
true
]
}
}
]
},
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"a" : 1,
"b" : 1,
"c" : 1,
"_id" : 0
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"a" : 1,
"b" : 1,
"c" : 1
},
"indexName" : "a_1_b_1_c_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"a" : [
"[\"string\", \"string\"]"
],
"b" : [
"[false, false]",
"[true, true]"
],
"c" : [
"[\"string\", \"string\"]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 2,
"executionTimeMillis" : 0,
"totalKeysExamined" : 2,
"totalDocsExamined" : 0,
"executionStages" : {
"stage" : "PROJECTION",
"nReturned" : 2,
"executionTimeMillisEstimate" : 0,
"works" : 3,
"advanced" : 2,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"transformBy" : {
"a" : 1,
"b" : 1,
"c" : 1,
"_id" : 0
},
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 2,
"executionTimeMillisEstimate" : 0,
"works" : 3,
"advanced" : 2,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"a" : 1,
"b" : 1,
"c" : 1
},
"indexName" : "a_1_b_1_c_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"a" : [
"[\"string\", \"string\"]"
],
"b" : [
"[false, false]",
"[true, true]"
],
"c" : [
"[\"string\", \"string\"]"
]
},
"keysExamined" : 2,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"serverInfo" : {
"host" : "VM-TOMLIN-HP",
"port" : 27017,
"version" : "3.2.6",
"gitVersion" : "05552b562c7a0b3143a729aaa0838e558dc49b25"
},
"ok" : 1
}
您使用的是什麼MongoDB版本?另外,你可以發佈兩個查詢的'explain()'結果嗎? –
@KevinAdistambha我正在使用3.2.6。在這個問題中增加了這個以及'explain()'輸出。 – Tom