I am trying to understand why MongoDB fails to use Index intersection as mentioned over here.
I have inserted 10000 documents in intersection
collection using the below code block:
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
for (var k = 0; k < 10; k++) {
for (var l = 0; l < 10; l++) {
db.intersection.insert({a:i, b:j, c:k, d:l});
}
}
}
}
Then created these 3 indexes:
db.intersection.createIndex({ a })
db.intersection.createIndex({ b : 1, c : 1 })
db.intersection.createIndex({ d : 1 })
At this point I was expecting db.intersection.find({a:1,b:2,d:4})
to use an intersection between the 3 indexes ie. a_1, b_1_c_1, d_1
However this isn't the case and I could see that the winning plan uses only one index, d_1
:
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"a" : {
"$eq" : 1
}
},
{
"b" : {
"$eq" : 2
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"d" : 1
},
"indexName" : "d_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"d" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"d" : [
"[4.0, 4.0]"
]
}
}
},
Sorry I'm unable to post the allPlansExecution since it exceeds the body word limit
Additionally, winning plan for db.inter.find({a:1,b:2})
also uses just one index, b_1_c_1
.
Can someone please provide an explanation for these results? Also a practical example demonstrating index intersection would be helpful.
Check this jira ticket on information about index intersection:
Apparently, mongodb can do better in most cases without using an index and it chooses to reject the intersection plan. It would be difficult to come up with an example which ensures that mongodb will use intersection.
For your example, if you see the rejectedPlans for the below query:
You'll find this as one of the plans (mongodb 3.4):
This (AND_SORTED stage) means mongodb did consider index intersection as a possibility, but concluded that d_1 index would perform much better.
Have a look at these answers too: here and here.