Why MongoDB query is slow while using index - mongodb

There is index in MongoDB:
{
"v" : 1,
"key" : {
"project_id" : 1,
"parse_date" : 1
},
"name" : "project_id_1_parse_date_1",
"ns" : "test.offer",
"partialFilterExpression" : {
"active" : false,
"errors" : {
"$exists" : true
}
},
"background" : true
}
But the query which uses this index is running very slow for no reason:
> db.currentOp()
{
"inprog" : [
{
"desc" : "conn16685",
"threadId" : "119533779793664",
"connectionId" : 16685,
"client" : "127.0.0.1:49154",
"active" : true,
"opid" : 100695187,
"secs_running" : 60,
"microsecs_running" : NumberLong(60950200),
"op" : "command",
"ns" : "test.offer",
"query" : {
"count" : "offer",
"query" : {
"project_id" : ObjectId("5818acae439a6b1e588b4568"),
"parse_date" : ISODate("2017-01-20T08:21:51.876Z"),
"active" : false,
"errors" : {
"$exists" : true
}
}
},
"planSummary" : "IXSCAN { project_id: 1.0, parse_date: 1.0 }",
"numYields" : 2422,
"locks" : {
"Global" : "r",
"Database" : "r",
"Collection" : "r"
},
"waitingForLock" : false,
"lockStats" : {
"Global" : {
"acquireCount" : {
"r" : NumberLong(4846)
}
},
"Database" : {
"acquireCount" : {
"r" : NumberLong(2423)
}
},
"Collection" : {
"acquireCount" : {
"r" : NumberLong(2423)
}
}
}
},
{
"desc" : "conn17711",
"threadId" : "119533772400384",
"connectionId" : 17711,
"client" : "127.0.0.1:45980",
"appName" : "MongoDB Shell",
"active" : true,
"opid" : 100827280,
"secs_running" : 0,
"microsecs_running" : NumberLong(73),
"op" : "command",
"ns" : "admin.$cmd",
"query" : {
"currentOp" : 1
},
"numYields" : 0,
"locks" : {
},
"waitingForLock" : false,
"lockStats" : {
}
}
],
"ok" : 1
}
Explain
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.offer",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"active" : {
"$eq" : false
}
},
{
"parse_date" : {
"$eq" : ISODate("2017-01-20T08:21:51.876Z")
}
},
{
"project_id" : {
"$eq" : ObjectId("5818acae439a6b1e588b4568")
}
},
{
"errors" : {
"$exists" : true
}
}
]
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"active" : {
"$eq" : false
}
},
{
"errors" : {
"$exists" : true
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"project_id" : 1,
"parse_date" : 1
},
"indexName" : "project_id_1_parse_date_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"project_id" : [ ],
"parse_date" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : true,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"project_id" : [
"[ObjectId('5818acae439a6b1e588b4568'), ObjectId('5818acae439a6b1e588b4568')]"
],
"parse_date" : [
"[new Date(1484900511876), new Date(1484900511876)]"
]
}
}
},
"rejectedPlans" : [
{
"stage" : "FETCH",
"filter" : {
"errors" : {
"$exists" : true
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"project_id" : 1,
"parse_date" : 1,
"active" : 1
},
"indexName" : "project_id_1_parse_date_1_active_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"project_id" : [ ],
"parse_date" : [ ],
"active" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"project_id" : [
"[ObjectId('5818acae439a6b1e588b4568'), ObjectId('5818acae439a6b1e588b4568')]"
],
"parse_date" : [
"[new Date(1484900511876), new Date(1484900511876)]"
],
"active" : [
"[false, false]"
]
}
}
},
{
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"parse_date" : {
"$eq" : ISODate("2017-01-20T08:21:51.876Z")
}
},
{
"errors" : {
"$exists" : true
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"project_id" : 1,
"active" : 1
},
"indexName" : "project_id_1_active_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"project_id" : [ ],
"active" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : true,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"project_id" : [
"[ObjectId('5818acae439a6b1e588b4568'), ObjectId('5818acae439a6b1e588b4568')]"
],
"active" : [
"[false, false]"
]
}
}
}
]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 8084,
"executionTimeMillis" : 21352,
"totalKeysExamined" : 8084,
"totalDocsExamined" : 8084,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"active" : {
"$eq" : false
}
},
{
"errors" : {
"$exists" : true
}
}
]
},
"nReturned" : 8084,
"executionTimeMillisEstimate" : 21333,
"works" : 8085,
"advanced" : 8084,
"needTime" : 0,
"needYield" : 0,
"saveState" : 998,
"restoreState" : 998,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 8084,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 8084,
"executionTimeMillisEstimate" : 120,
"works" : 8085,
"advanced" : 8084,
"needTime" : 0,
"needYield" : 0,
"saveState" : 998,
"restoreState" : 998,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"project_id" : 1,
"parse_date" : 1
},
"indexName" : "project_id_1_parse_date_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"project_id" : [ ],
"parse_date" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : true,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"project_id" : [
"[ObjectId('5818acae439a6b1e588b4568'), ObjectId('5818acae439a6b1e588b4568')]"
],
"parse_date" : [
"[new Date(1484900511876), new Date(1484900511876)]"
]
},
"keysExamined" : 8084,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
},
"allPlansExecution" : [
{
"nReturned" : 99,
"executionTimeMillisEstimate" : 0,
"totalKeysExamined" : 101,
"totalDocsExamined" : 101,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"errors" : {
"$exists" : true
}
},
"nReturned" : 99,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 99,
"needTime" : 2,
"needYield" : 0,
"saveState" : 6,
"restoreState" : 6,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 101,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 6,
"restoreState" : 6,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"project_id" : 1,
"parse_date" : 1,
"active" : 1
},
"indexName" : "project_id_1_parse_date_1_active_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"project_id" : [ ],
"parse_date" : [ ],
"active" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"project_id" : [
"[ObjectId('5818acae439a6b1e588b4568'), ObjectId('5818acae439a6b1e588b4568')]"
],
"parse_date" : [
"[new Date(1484900511876), new Date(1484900511876)]"
],
"active" : [
"[false, false]"
]
},
"keysExamined" : 101,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
{
"nReturned" : 3,
"executionTimeMillisEstimate" : 0,
"totalKeysExamined" : 101,
"totalDocsExamined" : 101,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"parse_date" : {
"$eq" : ISODate("2017-01-20T08:21:51.876Z")
}
},
{
"errors" : {
"$exists" : true
}
}
]
},
"nReturned" : 3,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 3,
"needTime" : 98,
"needYield" : 0,
"saveState" : 6,
"restoreState" : 6,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 101,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 6,
"restoreState" : 6,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"project_id" : 1,
"active" : 1
},
"indexName" : "project_id_1_active_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"project_id" : [ ],
"active" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : true,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"project_id" : [
"[ObjectId('5818acae439a6b1e588b4568'), ObjectId('5818acae439a6b1e588b4568')]"
],
"active" : [
"[false, false]"
]
},
"keysExamined" : 101,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
{
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"totalKeysExamined" : 101,
"totalDocsExamined" : 101,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"active" : {
"$eq" : false
}
},
{
"errors" : {
"$exists" : true
}
}
]
},
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 6,
"restoreState" : 6,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 101,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 6,
"restoreState" : 6,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"project_id" : 1,
"parse_date" : 1
},
"indexName" : "project_id_1_parse_date_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"project_id" : [ ],
"parse_date" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : true,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"project_id" : [
"[ObjectId('5818acae439a6b1e588b4568'), ObjectId('5818acae439a6b1e588b4568')]"
],
"parse_date" : [
"[new Date(1484900511876), new Date(1484900511876)]"
]
},
"keysExamined" : 101,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
]
},
"serverInfo" : {
"host" : "...",
"port" : 27017,
"version" : "3.4.1",
"gitVersion" : "5e103c4f5583e2566a45d740225dc250baacfbd7"
},
"ok" : 1
}
As you can see there are no other queries that can lock database or collection.
What can cause such behavior?

Related

MongoDb C# query performance

I have the MongoDB C# Driver 2.14.1 and a Mongo Server v3.6 running on a Docker container. I'm running an easy (I think) query over 3 collections. The biggest collection has 400k documents, each document averaged 64Kb. I'm filtering by two fields and returning the results in a cursor to reduce overhead. The results are sorted by descending by a field that is configured as an index as well. This is happening on my production server which is taking nearly 1GB of memory (not being released afterwards). The following queries explained (run on the server):
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "table1",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"Type" : {
"$eq" : "Type1"
}
},
{
"LocationId" : {
"$eq" : "Location1"
}
},
{
"Date" : {
"$gt" : ISODate("2021-01-18T23:00:00Z")
}
}
]
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"Type" : {
"$eq" : "Type1"
}
},
{
"LocationId" : {
"$eq" : "Location1"
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"Date" : -1
},
"indexName" : "Date_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"Date" : [ ]
},
"isUnique" : false,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"Date" : [
"[new Date(9223372036854775807), new Date(1611010800000))"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 2,
"totalKeysExamined" : 7,
"totalDocsExamined" : 7,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"Type" : {
"$eq" : "Type1"
}
},
{
"LocationId" : {
"$eq" : "Location1"
}
}
]
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 8,
"advanced" : 1,
"needTime" : 6,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 7,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 7,
"executionTimeMillisEstimate" : 0,
"works" : 8,
"advanced" : 7,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"Date" : -1
},
"indexName" : "Date_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"Date" : [ ]
},
"isUnique" : false,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"Date" : [
"[new Date(9223372036854775807), new Date(1611010800000))"
]
},
"keysExamined" : 7,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"serverInfo" : {
"host" : "7aa23bd7fe20",
"port" : 27018,
"version" : "3.6.18",
"gitVersion" : "2005f25eed7ed88fa698d9b800fe536bb0410ba4"
},
"ok" : 1
}
The second query:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "table2",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"Type" : {
"$eq" : "Type1"
}
},
{
"LocationId" : {
"$eq" : "02"
}
},
{
"Date" : {
"$gt" : ISODate("2021-01-18T23:00:00Z")
}
}
]
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"Type" : {
"$eq" : "Type1"
}
},
{
"LocationId" : {
"$eq" : "02"
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"Date" : -1
},
"indexName" : "Date_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"Date" : [ ]
},
"isUnique" : false,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"Date" : [
"[new Date(9223372036854775807), new Date(1611010800000))"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 63,
"totalKeysExamined" : 9896,
"totalDocsExamined" : 9896,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"Type" : {
"$eq" : "Type1"
}
},
{
"LocationId" : {
"$eq" : "02"
}
}
]
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 50,
"works" : 9897,
"advanced" : 1,
"needTime" : 9895,
"needYield" : 0,
"saveState" : 77,
"restoreState" : 77,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 9896,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 9896,
"executionTimeMillisEstimate" : 0,
"works" : 9897,
"advanced" : 9896,
"needTime" : 0,
"needYield" : 0,
"saveState" : 77,
"restoreState" : 77,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"Date" : -1
},
"indexName" : "Date_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"Date" : [ ]
},
"isUnique" : false,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"Date" : [
"[new Date(9223372036854775807), new Date(1611010800000))"
]
},
"keysExamined" : 9896,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"serverInfo" : {
"host" : "7aa23bd7fe20",
"port" : 27018,
"version" : "3.6.18",
"gitVersion" : "2005f25eed7ed88fa698d9b800fe536bb0410ba4"
},
"ok" : 1
}
And the third:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "table3",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"Type" : {
"$eq" : "Type1"
}
},
{
"LocationId" : {
"$eq" : "52"
}
},
{
"Date" : {
"$gt" : ISODate("2021-01-18T23:00:00Z")
}
}
]
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"Type" : {
"$eq" : "Type1"
}
},
{
"LocationId" : {
"$eq" : "52"
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"Date" : -1
},
"indexName" : "Date_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"Date" : [ ]
},
"isUnique" : false,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"Date" : [
"[new Date(9223372036854775807), new Date(1611010800000))"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 30,
"executionTimeMillis" : 934,
"totalKeysExamined" : 366370,
"totalDocsExamined" : 366370,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"Type" : {
"$eq" : "Type1"
}
},
{
"LocationId" : {
"$eq" : "52"
}
}
]
},
"nReturned" : 30,
"executionTimeMillisEstimate" : 889,
"works" : 366371,
"advanced" : 30,
"needTime" : 366340,
"needYield" : 0,
"saveState" : 2862,
"restoreState" : 2862,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 366370,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 366370,
"executionTimeMillisEstimate" : 160,
"works" : 366371,
"advanced" : 366370,
"needTime" : 0,
"needYield" : 0,
"saveState" : 2862,
"restoreState" : 2862,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"Date" : -1
},
"indexName" : "Date_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"Date" : [ ]
},
"isUnique" : false,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"Date" : [
"[new Date(9223372036854775807), new Date(1611010800000))"
]
},
"keysExamined" : 366370,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"serverInfo" : {
"host" : "7aa23bd7fe20",
"port" : 27018,
"version" : "3.6.18",
"gitVersion" : "2005f25eed7ed88fa698d9b800fe536bb0410ba4"
},
"ok" : 1
}
Now with my little knowledge of the "explainPlan" I would have imagined that the performance is OK, and not many records get returned on each query. Having said that I can see a pattern when I run the code via the .NET application (C# code) that makes the CPU go through the roof and right after the memory follows in the Mongo server Docker container.
I don't know if there is misconfigured or whether I can do something to improve the performance of it because I'm quite puzzle with the performance on just that query - I think is this query because the rest of the queries with similar amount of data on different parts of the system work quite well. Besides that, is there any mechanism or tool I can use to diagnose the memory consumption in my Mongo server?

MongoDB index doing a collection scan instead index scan [duplicate]

Here are the compound index and single index I have for this Collection:
///db.Collection.getIndexes()
/* 1 */
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "service.Collection"
},
/* 2 */
{
"v" : 2,
"key" : {
"FirstId" : 1,
"SecondId" : 1,
"CreationTime" : -1
},
"name" : "FirstIdSecondIdCreationTime",
"collation" : {
"locale" : "en",
"caseLevel" : false,
"caseFirst" : "off",
"strength" : 1,
"numericOrdering" : false,
"alternate" : "non-ignorable",
"maxVariable" : "punct",
"normalization" : false,
"backwards" : false,
"version" : "57.1"
},
"ns" : "service.Collection"
},
/* 3 */
{
"v" : 2,
"key" : {
"CreationTime" : 1
},
"name" : "CreationTime",
"collation" : {
"locale" : "en",
"caseLevel" : false,
"caseFirst" : "off",
"strength" : 1,
"numericOrdering" : false,
"alternate" : "non-ignorable",
"maxVariable" : "punct",
"normalization" : false,
"backwards" : false,
"version" : "57.1"
},
"ns" : "service.Collection"
}
The expected result is an IXSCAN using the FirstIdSecondIdCreationTime index:
///service.Collection.find({ FirstId: "771367b7-4bef-49ab-bda1-6230254c6349", ///SecondId: "3bffb3cd-fb5e-43e5-abd1-e0b48c97f78f" })
/// .projection({})
/// .sort({_id:-1}).hint("FirstIdSecondIdCreationTime").explain('executionStats')
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "service.Collection",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"FirstId" : {
"$eq" : "771367b7-4bef-49ab-bda1-6230254c6349"
}
},
{
"SecondId" : {
"$eq" : "3bffb3cd-fb5e-43e5-abd1-e0b48c97f78f"
}
}
]
},
"winningPlan" : {
"stage" : "SORT",
"sortPattern" : {
"_id" : -1
},
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"FirstId" : {
"$eq" : "771367b7-4bef-49ab-bda1-6230254c6349"
}
},
{
"SecondId" : {
"$eq" : "3bffb3cd-fb5e-43e5-abd1-e0b48c97f78f"
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"FirstId" : 1,
"SecondId" : 1,
"CreationTime" : -1
},
"indexName" : "FirstIdSecondIdCreationTime",
"collation" : {
"locale" : "en",
"caseLevel" : false,
"caseFirst" : "off",
"strength" : 1,
"numericOrdering" : false,
"alternate" : "non-ignorable",
"maxVariable" : "punct",
"normalization" : false,
"backwards" : false,
"version" : "57.1"
},
"isMultiKey" : false,
"multiKeyPaths" : {
"FirstId" : [ ],
"SecondId" : [ ],
"CreationTime" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"FirstId" : [
"[MinKey, MaxKey]"
],
"SecondId" : [
"[MinKey, MaxKey]"
],
"CreationTime" : [
"[MaxKey, MinKey]"
]
}
}
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 5491,
"totalKeysExamined" : 856730,
"totalDocsExamined" : 856730,
"executionStages" : {
"stage" : "SORT",
"nReturned" : 1,
"executionTimeMillisEstimate" : 5261,
"works" : 856734,
"advanced" : 1,
"needTime" : 856732,
"needYield" : 0,
"saveState" : 6697,
"restoreState" : 6697,
"isEOF" : 1,
"invalidates" : 0,
"sortPattern" : {
"_id" : -1
},
"memUsage" : 432,
"memLimit" : 33554432,
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"nReturned" : 1,
"executionTimeMillisEstimate" : 5201,
"works" : 856732,
"advanced" : 1,
"needTime" : 856730,
"needYield" : 0,
"saveState" : 6697,
"restoreState" : 6697,
"isEOF" : 1,
"invalidates" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"FirstId" : {
"$eq" : "771367b7-4bef-49ab-bda1-6230254c6349"
}
},
{
"SecondId" : {
"$eq" : "3bffb3cd-fb5e-43e5-abd1-e0b48c97f78f"
}
}
]
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 5131,
"works" : 856731,
"advanced" : 1,
"needTime" : 856729,
"needYield" : 0,
"saveState" : 6697,
"restoreState" : 6697,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 856730,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 856730,
"executionTimeMillisEstimate" : 820,
"works" : 856731,
"advanced" : 856730,
"needTime" : 0,
"needYield" : 0,
"saveState" : 6697,
"restoreState" : 6697,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"FirstId" : 1,
"SecondId" : 1,
"CreationTime" : -1
},
"indexName" : "FirstIdSecondIdCreationTime",
"collation" : {
"locale" : "en",
"caseLevel" : false,
"caseFirst" : "off",
"strength" : 1,
"numericOrdering" : false,
"alternate" : "non-ignorable",
"maxVariable" : "punct",
"normalization" : false,
"backwards" : false,
"version" : "57.1"
},
"isMultiKey" : false,
"multiKeyPaths" : {
"FirstId" : [ ],
"SecondId" : [ ],
"CreationTime" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"FirstId" : [
"[MinKey, MaxKey]"
],
"SecondId" : [
"[MinKey, MaxKey]"
],
"CreationTime" : [
"[MaxKey, MinKey]"
]
},
"keysExamined" : 856730,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"indexDef" : {
"indexName" : "FirstIdSecondIdCreationTime",
"isMultiKey" : false,
"multiKeyPaths" : {
"FirstId" : [ ],
"SecondId" : [ ],
"CreationTime" : [ ]
},
"keyPattern" : {
"FirstId" : 1,
"SecondId" : 1,
"CreationTime" : -1
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"direction" : "forward"
}
}
}
}
}
but the actual result is a COLLSCAN that takes over 8000ms:
"event": {
"dataset": "mongodb.log",
"module": "mongodb"
},
"service": {
"type": "mongodb"
},
"message": "command service.Collection command: find { find: \"Collection\",
filter: { FirstId: \"771367b7-4bef-49ab-bda1-6230254c6349\", SecondId: \"3bffb3cd-fb5e-43e5-abd1-e0b48c97f78f\" }, sort: { CreationTime: -1 }, limit: 1,
planSummary: COLLSCAN keysExamined:0 docsExamined:784787 hasSortStage:1 cursorExhausted:1 numYields:6175 nreturned:1 reslen:677
locks:{ Global: { acquireCount: { r: 12352 } }, Database: { acquireCount: { r: 6176 } }, Collection: { acquireCount: { r: 6176 } } } protocol:op_msg 8441ms",
"mongodb.docsExamined": 784787,
"fileset": {
"name": "log"
},
Why am I COLLSCANing instead of IXSCANing with the FirstIdSecondIDCreationTime compound index? Is there a way to change my index/ my query to speed up the query?
Per a suggestion in the comments, I've run explain("allPlansExecution").
///db.Collection.find({ FirstId: "771367b7-4bef-49ab-bda1-6230254c6349", ///SecondId: "3bffb3cd-fb5e-43e5-abd1-e0b48c97f78f" })
/// .projection({})
/// .sort({_id:-1}).explain('allPlansExecution')
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "service.Collection",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"FirstId" : {
"$eq" : "771367b7-4bef-49ab-bda1-6230254c6349"
}
},
{
"SecondId" : {
"$eq" : "3bffb3cd-fb5e-43e5-abd1-e0b48c97f78f"
}
}
]
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"FirstId" : {
"$eq" : "771367b7-4bef-49ab-bda1-6230254c6349"
}
},
{
"SecondId" : {
"$eq" : "3bffb3cd-fb5e-43e5-abd1-e0b48c97f78f"
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"_id" : 1
},
"indexName" : "_id_",
"isMultiKey" : false,
"multiKeyPaths" : {
"_id" : [ ]
},
"isUnique" : true,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "backward",
"indexBounds" : {
"_id" : [
"[MaxKey, MinKey]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 5408,
"totalKeysExamined" : 856748,
"totalDocsExamined" : 856748,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"FirstId" : {
"$eq" : "771367b7-4bef-49ab-bda1-6230254c6349"
}
},
{
"SecondId" : {
"$eq" : "3bffb3cd-fb5e-43e5-abd1-e0b48c97f78f"
}
}
]
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 4862,
"works" : 856749,
"advanced" : 1,
"needTime" : 856747,
"needYield" : 0,
"saveState" : 6694,
"restoreState" : 6694,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 856748,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 856748,
"executionTimeMillisEstimate" : 1220,
"works" : 856749,
"advanced" : 856748,
"needTime" : 0,
"needYield" : 0,
"saveState" : 6694,
"restoreState" : 6694,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"_id" : 1
},
"indexName" : "_id_",
"isMultiKey" : false,
"multiKeyPaths" : {
"_id" : [ ]
},
"isUnique" : true,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "backward",
"indexBounds" : {
"_id" : [
"[MaxKey, MinKey]"
]
},
"keysExamined" : 856748,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
},
"allPlansExecution" : [ ]
}
}
The "FirstIdSecondIdCreationTime" index was not automatically considered because it was created with a collation, and the query is being run without a collation.
Use the .collation() cursor method to specify the same collation for the query that was used for the index.
The 5.5 second run time using that index is pretty slow as well.
You may see some improvement in that query if you create an index on {FirstId: 1, SecondId: 1, _id: 1} so that they query executor can use the index to meet the sort instead of an in-memory sort.
Can you please sort by leading indexes i.e firstId, secondId and creationTime in the same sequence and see index is used. it will give an idea whether leading indexes fields should be there in sort as well.

mongodb 4.2 sort by id slow with compound index

I have docs in the fasion
{
_id: ...,
p: [
{
k: 'stringvalue',
v: 'stringvalue'
},
...
]
}
_id is provided to drivers as a sequence number of insertion, e.g. ...0001, ....0002, etc.
That works extermely well for find queries, now I have added sort condition and added _id field to the compound index (see below).
That works extermely bad around x100 slower, what could be the reason? The server has plenty of RAM.
db.getCollection('mycoll').find({ p: { '$elemMatch': { k: 'd', v: { '$gt': '2019-10-16T08:01:39.741' } } } }).sort({_id: 1}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "mydb.mycoll",
"indexFilterSet" : false,
"parsedQuery" : {
"p" : {
"$elemMatch" : {
"$and" : [
{
"k" : {
"$eq" : "d"
}
},
{
"v" : {
"$gt" : "2019-10-16T08:01:39.741"
}
}
]
}
}
},
"queryHash" : "E28632C1",
"planCacheKey" : "E28632C1",
"winningPlan" : {
"stage" : "SORT",
"sortPattern" : {
"_id" : 1
},
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"p" : {
"$elemMatch" : {
"$and" : [
{
"k" : {
"$eq" : "d"
}
},
{
"v" : {
"$gt" : "2019-10-16T08:01:39.741"
}
}
]
}
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"p.k" : 1,
"p.v" : 1,
"_id" : 1
},
"indexName" : "p.k_1_p.v_1__id_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"p.k" : [
"p"
],
"p.v" : [
"p"
],
"_id" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"p.k" : [
"[\"d\", \"d\"]"
],
"p.v" : [
"(\"2019-10-16T08:01:39.741\", {})"
],
"_id" : [
"[MinKey, MaxKey]"
]
}
}
}
}
},
"rejectedPlans" : [
{
"stage" : "FETCH",
"filter" : {
"p" : {
"$elemMatch" : {
"$and" : [
{
"k" : {
"$eq" : "d"
}
},
{
"v" : {
"$gt" : "2019-10-16T08:01:39.741"
}
}
]
}
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"_id" : 1
},
"indexName" : "_id_",
"isMultiKey" : false,
"multiKeyPaths" : {
"_id" : [ ]
},
"isUnique" : true,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"_id" : [
"[MinKey, MaxKey]"
]
}
}
}
]
},
"serverInfo" : {
"host" : "dev-10-178-3-247",
"port" : 27017,
"version" : "4.2.0",
"gitVersion" : "a4b751dcf51dd249c5865812b390cfd1c0129c30"
},
"ok" : 1
}
> db.getCollection('mycoll').getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "mydb.mycoll"
},
{
"v" : 2,
"key" : {
"p.k" : 1,
"p.v" : 1,
"_id" : 1
},
"name" : "p.k_1_p.v_1__id_1",
"ns" : "mydb.mycoll"
}
]
{
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1015268,
"executionTimeMillis" : 77032,
"totalKeysExamined" : 3122749,
"totalDocsExamined" : 3122749,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"p" : {
"$elemMatch" : {
"$and" : [
{
"k" : {
"$eq" : "d"
}
},
{
"v" : {
"$gt" : "2019-10-16T08:01:39.741"
}
}
]
}
}
},
"nReturned" : 1015268,
"executionTimeMillisEstimate" : 16092,
"works" : 3122750,
"advanced" : 1015268,
"needTime" : 2107481,
"needYield" : 0,
"saveState" : 24469,
"restoreState" : 24469,
"isEOF" : 1,
"docsExamined" : 3122749,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 3122749,
"executionTimeMillisEstimate" : 492,
"works" : 3122750,
"advanced" : 3122749,
"needTime" : 0,
"needYield" : 0,
"saveState" : 24469,
"restoreState" : 24469,
"isEOF" : 1,
"keyPattern" : {
"_id" : 1
},
"indexName" : "_id_",
"isMultiKey" : false,
"multiKeyPaths" : {
"_id" : [ ]
},
"isUnique" : true,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"_id" : [
"[MinKey, MaxKey]"
]
},
"keysExamined" : 3122749,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0
}
},
"allPlansExecution" : [
{
"nReturned" : 0,
"executionTimeMillisEstimate" : 85,
"totalKeysExamined" : 9298,
"totalDocsExamined" : 9298,
"executionStages" : {
"stage" : "SORT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 85,
"works" : 9300,
"advanced" : 0,
"needTime" : 9299,
"needYield" : 0,
"saveState" : 7391,
"restoreState" : 7391,
"isEOF" : 0,
"sortPattern" : {
"_id" : 1
},
"memUsage" : 33559558,
"memLimit" : 33554432,
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"nReturned" : 9298,
"executionTimeMillisEstimate" : 71,
"works" : 9299,
"advanced" : 9298,
"needTime" : 1,
"needYield" : 0,
"saveState" : 7391,
"restoreState" : 7391,
"isEOF" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"p" : {
"$elemMatch" : {
"$and" : [
{
"k" : {
"$eq" : "d"
}
},
{
"v" : {
"$gt" : "2019-10-16T08:01:39.741"
}
}
]
}
}
},
"nReturned" : 9298,
"executionTimeMillisEstimate" : 58,
"works" : 9298,
"advanced" : 9298,
"needTime" : 0,
"needYield" : 0,
"saveState" : 7391,
"restoreState" : 7391,
"isEOF" : 0,
"docsExamined" : 9298,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 9298,
"executionTimeMillisEstimate" : 0,
"works" : 9298,
"advanced" : 9298,
"needTime" : 0,
"needYield" : 0,
"saveState" : 7391,
"restoreState" : 7391,
"isEOF" : 0,
"keyPattern" : {
"p.k" : 1,
"p.v" : 1,
"_id" : 1
},
"indexName" : "p.k_1_p.v_1__id_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"p.k" : [
"p"
],
"p.v" : [
"p"
],
"_id" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"p.k" : [
"[\"d\", \"d\"]"
],
"p.v" : [
"(\"2019-10-16T08:01:39.741\", {})"
],
"_id" : [
"[MinKey, MaxKey]"
]
},
"keysExamined" : 9298,
"seeks" : 1,
"dupsTested" : 9298,
"dupsDropped" : 0
}
}
}
}
},
{
"nReturned" : 0,
"executionTimeMillisEstimate" : 85,
"totalKeysExamined" : 9298,
"totalDocsExamined" : 9298,
"executionStages" : {
"stage" : "SORT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 85,
"works" : 9301,
"advanced" : 0,
"needTime" : 9299,
"needYield" : 0,
"saveState" : 24469,
"restoreState" : 24469,
"isEOF" : 0,
"sortPattern" : {
"_id" : 1
},
"memUsage" : 33559558,
"memLimit" : 33554432,
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"nReturned" : 9298,
"executionTimeMillisEstimate" : 71,
"works" : 9299,
"advanced" : 9298,
"needTime" : 1,
"needYield" : 0,
"saveState" : 24469,
"restoreState" : 24469,
"isEOF" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"p" : {
"$elemMatch" : {
"$and" : [
{
"k" : {
"$eq" : "d"
}
},
{
"v" : {
"$gt" : "2019-10-16T08:01:39.741"
}
}
]
}
}
},
"nReturned" : 9298,
"executionTimeMillisEstimate" : 58,
"works" : 9298,
"advanced" : 9298,
"needTime" : 0,
"needYield" : 0,
"saveState" : 24469,
"restoreState" : 24469,
"isEOF" : 0,
"docsExamined" : 9298,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 9298,
"executionTimeMillisEstimate" : 0,
"works" : 9298,
"advanced" : 9298,
"needTime" : 0,
"needYield" : 0,
"saveState" : 24469,
"restoreState" : 24469,
"isEOF" : 0,
"keyPattern" : {
"p.k" : 1,
"p.v" : 1,
"_id" : 1
},
"indexName" : "p.k_1_p.v_1__id_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"p.k" : [
"p"
],
"p.v" : [
"p"
],
"_id" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"p.k" : [
"[\"d\", \"d\"]"
],
"p.v" : [
"(\"2019-10-16T08:01:39.741\", {})"
],
"_id" : [
"[MinKey, MaxKey]"
]
},
"keysExamined" : 9298,
"seeks" : 1,
"dupsTested" : 9298,
"dupsDropped" : 0
}
}
}
}
}
]
},
"ok" : 1
}

Index intersection queries performing the same as COLLSCAN

I'm going through the existing indexes on a fairly old MongoDB database which has recently been upgraded from 2.something to 3.4.
The code accessing it is convoluted, automagic, and spaghetti-heavy, plus it allows web-facing frontend code to do arbitrary queries, so it's pretty difficult to get an overview of exactly what queries are made. Doing a bit of profiling, I quickly discovered that a lot of queries were missing indexes, either because logical indexes were missing or misspelled (yeah!), or because someone had assumed that a compound index would support queries on non-prefix parts of them.
Such an example was with a users collection where a compound index, { boxes._id: 1, _deleted: 1 } was missed by a ton of queries filtering by { _deleted: { $exists: false } }.
I wiped it, and created single-field indexes instead, having read up on the index intersection feature which is now part of the version of the MongoDB server backing this app:
db.users.dropIndex({ 'boxes._id': 1, _deleted: 1 });
db.users.ensureIndex({ 'boxes._id': 1 });
db.users.ensureIndex({ '_deleted': 1 });
So far, so good. The dataset here is not very large, so I saw no immediate issue, performance-wise, by dropping the compound index and support index intersection instead. AFAIU from the docs and the interwebs, the performance gains from using compound indexes are mostly felt with really large collections, and for this one, we're looking at about 11k documents.
Simple count queries on either of the two indexed fields yield satisfying responses while hitting the keys:
db.runCommand({ explain: { count: 'users', query: { 'boxes._id': ObjectId('597745846ca2582d8b364c38') }, verbosity: 'executionStats' }})
// "executionTimeMillis" : 8
db.runCommand({ explain: { count: 'users', query: { _deleted: { $exists: false } }, verbosity: 'executionStats' }})
// "executionTimeMillis" : 35
(Note that this is on my old MacBook Air, and compared to query times I'm seeing in the performance log when not using explain, then "normal" response times seem to be less than 25% of those reported with explain in the mongo shell)
However, if I filter on both those fields thus triggering the use of an intersection index, I see a massive performance penalty:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "bl.users",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"boxes._id" : {
"$eq" : ObjectId("597745846ca2582d8b364c38")
}
},
{
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
}
]
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
},
{
"boxes._id" : {
"$eq" : ObjectId("597745846ca2582d8b364c38")
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : { "_deleted" : 1 },
"indexName" : "_deleted_1",
"isMultiKey" : false,
"multiKeyPaths" : { "_deleted" : [ ] },
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : { "_deleted" : [ "[null, null]" ] }
}
},
"rejectedPlans" : [
{
"stage" : "FETCH",
"filter" : {
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"boxes._id" : 1
},
"indexName" : "boxes._id_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"boxes._id" : [
"boxes"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"boxes._id" : [
"[ObjectId('597745846ca2582d8b364c38'), ObjectId('597745846ca2582d8b364c38')]"
]
}
}
},
{
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"boxes._id" : {
"$eq" : ObjectId("597745846ca2582d8b364c38")
}
},
{
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
}
]
},
"inputStage" : {
"stage" : "AND_SORTED",
"inputStages" : [
{
"stage" : "IXSCAN",
"keyPattern" : {
"boxes._id" : 1
},
"indexName" : "boxes._id_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"boxes._id" : [
"boxes"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"boxes._id" : [
"[ObjectId('597745846ca2582d8b364c38'), ObjectId('597745846ca2582d8b364c38')]"
]
}
},
{
"stage" : "IXSCAN",
"keyPattern" : { "_deleted" : 1 },
"indexName" : "_deleted_1",
"isMultiKey" : false,
"multiKeyPaths" : { "_deleted" : [ ] },
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"_deleted" : [ "[null, null]" ]
}
}
]
}
}
]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 11098,
"executionTimeMillis" : 731,
"totalKeysExamined" : 11098,
"totalDocsExamined" : 11098,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
},
{
"boxes._id" : {
"$eq" : ObjectId("597745846ca2582d8b364c38")
}
}
]
},
"nReturned" : 11098,
"executionTimeMillisEstimate" : 702,
"works" : 11099,
"advanced" : 11098,
"needTime" : 0,
"needYield" : 0,
"saveState" : 127,
"restoreState" : 127,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 11098,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 11098,
"executionTimeMillisEstimate" : 49,
"works" : 11099,
"advanced" : 11098,
"needTime" : 0,
"needYield" : 0,
"saveState" : 127,
"restoreState" : 127,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : { "_deleted" : 1 },
"indexName" : "_deleted_1",
"isMultiKey" : false,
"multiKeyPaths" : { "_deleted" : [ ] },
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"_deleted" : [ "[null, null]" ]
},
"keysExamined" : 11098,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
},
"allPlansExecution" : [
{
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"totalKeysExamined" : 101,
"totalDocsExamined" : 101,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
},
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 3,
"restoreState" : 3,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 101,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 3,
"restoreState" : 3,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"boxes._id" : 1
},
"indexName" : "boxes._id_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"boxes._id" : [
"boxes"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"boxes._id" : [
"[ObjectId('597745846ca2582d8b364c38'), ObjectId('597745846ca2582d8b364c38')]"
]
},
"keysExamined" : 101,
"seeks" : 1,
"dupsTested" : 101,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
{
"nReturned" : 50,
"executionTimeMillisEstimate" : 12,
"totalKeysExamined" : 101,
"totalDocsExamined" : 50,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"boxes._id" : {
"$eq" : ObjectId("597745846ca2582d8b364c38")
}
},
{
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
}
]
},
"nReturned" : 50,
"executionTimeMillisEstimate" : 12,
"works" : 101,
"advanced" : 50,
"needTime" : 51,
"needYield" : 0,
"saveState" : 3,
"restoreState" : 3,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 50,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "AND_SORTED",
"nReturned" : 50,
"executionTimeMillisEstimate" : 12,
"works" : 101,
"advanced" : 50,
"needTime" : 51,
"needYield" : 0,
"saveState" : 3,
"restoreState" : 3,
"isEOF" : 0,
"invalidates" : 0,
"flagged" : 0,
"failedAnd_0" : 0,
"failedAnd_1" : 0,
"inputStages" : [
{
"stage" : "IXSCAN",
"nReturned" : 51,
"executionTimeMillisEstimate" : 0,
"works" : 51,
"advanced" : 51,
"needTime" : 0,
"needYield" : 0,
"saveState" : 3,
"restoreState" : 3,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"boxes._id" : 1
},
"indexName" : "boxes._id_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"boxes._id" : [
"boxes"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"boxes._id" : [
"[ObjectId('597745846ca2582d8b364c38'), ObjectId('597745846ca2582d8b364c38')]"
]
},
"keysExamined" : 51,
"seeks" : 1,
"dupsTested" : 51,
"dupsDropped" : 0,
"seenInvalidated" : 0
},
{
"stage" : "IXSCAN",
"nReturned" : 50,
"executionTimeMillisEstimate" : 12,
"works" : 50,
"advanced" : 50,
"needTime" : 0,
"needYield" : 0,
"saveState" : 3,
"restoreState" : 3,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : { "_deleted" : 1 },
"indexName" : "_deleted_1",
"isMultiKey" : false,
"multiKeyPaths" : { "_deleted" : [ ] },
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"_deleted" : [ "[null, null]" ]
},
"keysExamined" : 50,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
]
}
}
},
{
"nReturned" : 101,
"executionTimeMillisEstimate" : 11,
"totalKeysExamined" : 101,
"totalDocsExamined" : 101,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
},
{
"boxes._id" : {
"$eq" : ObjectId("597745846ca2582d8b364c38")
}
}
]
},
"nReturned" : 101,
"executionTimeMillisEstimate" : 11,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 3,
"restoreState" : 3,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 101,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 3,
"restoreState" : 3,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : { "_deleted" : 1 },
"indexName" : "_deleted_1",
"isMultiKey" : false,
"multiKeyPaths" : { "_deleted" : [ ] },
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"_deleted" : [ "[null, null]" ]
},
"keysExamined" : 101,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
]
}
}
The same query hitting the compound index:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "bl.users",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"boxes._id" : {
"$eq" : ObjectId("597745846ca2582d8b364c38")
}
},
{
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
}
]
},
"winningPlan" : {
"stage" : "COUNT",
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"boxes._id" : 1,
"_deleted" : 1
},
"indexName" : "boxes._id_1__deleted_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"boxes._id" : [
"boxes"
],
"_deleted" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"boxes._id" : [
"[ObjectId('597745846ca2582d8b364c38'), ObjectId('597745846ca2582d8b364c38')]"
],
"_deleted" : [ "[null, null]" ]
}
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 37,
"totalKeysExamined" : 11098,
"totalDocsExamined" : 11098,
"executionStages" : {
"stage" : "COUNT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 35,
"works" : 11099,
"advanced" : 0,
"needTime" : 11098,
"needYield" : 0,
"saveState" : 87,
"restoreState" : 87,
"isEOF" : 1,
"invalidates" : 0,
"nCounted" : 11098,
"nSkipped" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
},
"nReturned" : 11098,
"executionTimeMillisEstimate" : 35,
"works" : 11099,
"advanced" : 11098,
"needTime" : 0,
"needYield" : 0,
"saveState" : 87,
"restoreState" : 87,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 11098,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 11098,
"executionTimeMillisEstimate" : 23,
"works" : 11099,
"advanced" : 11098,
"needTime" : 0,
"needYield" : 0,
"saveState" : 87,
"restoreState" : 87,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"boxes._id" : 1,
"_deleted" : 1
},
"indexName" : "boxes._id_1__deleted_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"boxes._id" : [
"boxes"
],
"_deleted" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"boxes._id" : [
"[ObjectId('597745846ca2582d8b364c38'), ObjectId('597745846ca2582d8b364c38')]"
],
"_deleted" : [ "[null, null]" ]
},
"keysExamined" : 11098,
"seeks" : 1,
"dupsTested" : 11098,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"allPlansExecution" : [ ]
}
}
Replacing the compound index with just a single index on boxes._id yields pretty much identical performance to having the compound key on both filtered fields:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "bl.users",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"boxes._id" : {
"$eq" : ObjectId("597745846ca2582d8b364c38")
}
},
{
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
}
]
},
"winningPlan" : {
"stage" : "COUNT",
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"boxes._id" : 1
},
"indexName" : "boxes._id_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"boxes._id" : [
"boxes"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"boxes._id" : [
"[ObjectId('597745846ca2582d8b364c38'), ObjectId('597745846ca2582d8b364c38')]"
]
}
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 31,
"totalKeysExamined" : 11098,
"totalDocsExamined" : 11098,
"executionStages" : {
"stage" : "COUNT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 34,
"works" : 11099,
"advanced" : 0,
"needTime" : 11098,
"needYield" : 0,
"saveState" : 88,
"restoreState" : 88,
"isEOF" : 1,
"invalidates" : 0,
"nCounted" : 11098,
"nSkipped" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
},
"nReturned" : 11098,
"executionTimeMillisEstimate" : 34,
"works" : 11099,
"advanced" : 11098,
"needTime" : 0,
"needYield" : 0,
"saveState" : 88,
"restoreState" : 88,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 11098,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 11098,
"executionTimeMillisEstimate" : 11,
"works" : 11099,
"advanced" : 11098,
"needTime" : 0,
"needYield" : 0,
"saveState" : 88,
"restoreState" : 88,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"boxes._id" : 1
},
"indexName" : "boxes._id_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"boxes._id" : [
"boxes"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"boxes._id" : [
"[ObjectId('597745846ca2582d8b364c38'), ObjectId('597745846ca2582d8b364c38')]"
]
},
"keysExamined" : 11098,
"seeks" : 1,
"dupsTested" : 11098,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"allPlansExecution" : [ ]
}
}
Finally, dropping all indexes on these fields, triggering a COLLSCAN yields performance pretty much identical to the index intersection one:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "bl.users",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"ideaboxes._id" : {
"$eq" : ObjectId("597745846ca2582d8b364c38")
}
},
{
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
}
]
},
"winningPlan" : {
"stage" : "COUNT",
"inputStage" : {
"stage" : "COLLSCAN",
"filter" : {
"$and" : [
{
"ideaboxes._id" : {
"$eq" : ObjectId("597745846ca2582d8b364c38")
}
},
{
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
}
]
},
"direction" : "forward"
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 848,
"totalKeysExamined" : 0,
"totalDocsExamined" : 11109,
"executionStages" : {
"stage" : "COUNT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 847,
"works" : 11111,
"advanced" : 0,
"needTime" : 11110,
"needYield" : 0,
"saveState" : 123,
"restoreState" : 123,
"isEOF" : 1,
"invalidates" : 0,
"nCounted" : 11098,
"nSkipped" : 0,
"inputStage" : {
"stage" : "COLLSCAN",
"filter" : {
"$and" : [
{
"ideaboxes._id" : {
"$eq" : ObjectId("597745846ca2582d8b364c38")
}
},
{
"$nor" : [ { "_deleted" : { "$exists" : true } } ]
}
]
},
"nReturned" : 11098,
"executionTimeMillisEstimate" : 847,
"works" : 11111,
"advanced" : 11098,
"needTime" : 12,
"needYield" : 0,
"saveState" : 123,
"restoreState" : 123,
"isEOF" : 1,
"invalidates" : 0,
"direction" : "forward",
"docsExamined" : 11109
}
},
"allPlansExecution" : [ ]
}
}
Surely getting COLLSCAN performance with index intersection queries can't be right? I admit I'm very new with Mongo, so I'm also quite ignorant when trying to decipher this report — the answer may be staring me in the face.
I've tested the same queries on Mongo 3.2 on an ObjectRocket instance, and while their servers are much faster than my ageing laptop, they exhibit the same numbers relatively speaking.
Any ideas why this is happening?
Thank you :)

MongoDB Not Using Index for $in or $or Queries

I have a MongoDB collection with about 350k documents in it, and I am doing simple count queries based on one of the integer fields, usually using $in. The field is indexed with both db.myColl.createIndex({indexedField: 1}) and db.myColl.createIndex({indexedField: -1}).
When I run a query matching one value, the response comes quickly, as expected:
> db.myColl.explain("executionStats").count({indexedField: 1})
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "myDb.myColl",
"indexFilterSet" : false,
"parsedQuery" : {
"indexedField" : {
"$eq" : 1
}
},
"winningPlan" : {
"stage" : "COUNT",
"inputStage" : {
"stage" : "COUNT_SCAN",
"keyPattern" : {
"indexedField" : 1
},
"indexName" : "indexedField_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"indexedField" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"indexBounds" : {
"startKey" : {
"indexedField" : 1
},
"startKeyInclusive" : true,
"endKey" : {
"indexedField" : 1
},
"endKeyInclusive" : true
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 171,
"totalKeysExamined" : 354783,
"totalDocsExamined" : 0,
"executionStages" : {
"stage" : "COUNT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 101,
"works" : 354783,
"advanced" : 0,
"needTime" : 354782,
"needYield" : 0,
"saveState" : 2772,
"restoreState" : 2772,
"isEOF" : 1,
"invalidates" : 0,
"nCounted" : 354782,
"nSkipped" : 0,
"inputStage" : {
"stage" : "COUNT_SCAN",
"nReturned" : 354782,
"executionTimeMillisEstimate" : 91,
"works" : 354783,
"advanced" : 354782,
"needTime" : 0,
"needYield" : 0,
"saveState" : 2772,
"restoreState" : 2772,
"isEOF" : 1,
"invalidates" : 0,
"keysExamined" : 354783,
"keyPattern" : {
"indexedField" : 1
},
"indexName" : "indexedField_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"indexedField" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"indexBounds" : {
"startKey" : {
"indexedField" : 1
},
"startKeyInclusive" : true,
"endKey" : {
"indexedField" : 1
},
"endKeyInclusive" : true
}
}
}
},
"serverInfo" : {
"host" : "...",
"port" : 27017,
"version" : "3.4.4",
"gitVersion" : "888390515874a9debd1b6c5d36559ca86b44babd"
},
"ok" : 1
}
However, when I attempt to query for more than one value for indexedField using $in, it slows to a crawl:
> db.myColl.explain("executionStats").count({indexedField: {$in: [1, 2]}})
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "myDb.myColl",
"indexFilterSet" : false,
"parsedQuery" : {
"indexedField" : {
"$in" : [
1,
2
]
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"indexedField" : 1
},
"indexName" : "indexedField_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"indexedField" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"indexedField" : [
"[1.0, 1.0]",
"[2.0, 2.0]"
]
}
}
},
"rejectedPlans" : [
{
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"indexedField" : -1
},
"indexName" : "indexedField_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"indexedField" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"indexedField" : [
"[2.0, 2.0]",
"[1.0, 1.0]"
]
}
}
}
]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 354782,
"executionTimeMillis" : 215153,
"totalKeysExamined" : 354782,
"totalDocsExamined" : 354782,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 354782,
"executionTimeMillisEstimate" : 214871,
"works" : 354783,
"advanced" : 354782,
"needTime" : 0,
"needYield" : 0,
"saveState" : 11371,
"restoreState" : 11371,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 354782,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 354782,
"executionTimeMillisEstimate" : 748,
"works" : 354783,
"advanced" : 354782,
"needTime" : 0,
"needYield" : 0,
"saveState" : 11371,
"restoreState" : 11371,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"indexedField" : 1
},
"indexName" : "indexedField_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"indexedField" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"indexedField" : [
"[1.0, 1.0]",
"[2.0, 2.0]"
]
},
"keysExamined" : 354782,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"serverInfo" : {
"host" : "...",
"port" : 27017,
"version" : "3.4.4",
"gitVersion" : "888390515874a9debd1b6c5d36559ca86b44babd"
},
"ok" : 1
}
Using $or instead of $in yields similar bad results:
> db.myColl.explain("executionStats").count({$or: [{indexedField: 1}, {indexedField: 2}] })
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "myDb.myColl",
"indexFilterSet" : false,
"parsedQuery" : {
"$or" : [
{
"indexedField" : {
"$eq" : 1
}
},
{
"indexedField" : {
"$eq" : 2
}
}
]
},
"winningPlan" : {
"stage" : "COUNT",
"inputStage" : {
"stage" : "SUBPLAN",
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"indexedField" : 1
},
"indexName" : "indexedField_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"indexedField" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"indexedField" : [
"[1.0, 1.0]",
"[2.0, 2.0]"
]
}
}
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 219269,
"totalKeysExamined" : 354782,
"totalDocsExamined" : 354782,
"executionStages" : {
"stage" : "COUNT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 219170,
"works" : 354783,
"advanced" : 0,
"needTime" : 354782,
"needYield" : 0,
"saveState" : 11384,
"restoreState" : 11384,
"isEOF" : 1,
"invalidates" : 0,
"nCounted" : 354782,
"nSkipped" : 0,
"inputStage" : {
"stage" : "SUBPLAN",
"nReturned" : 354782,
"executionTimeMillisEstimate" : 219090,
"works" : 354783,
"advanced" : 354782,
"needTime" : 0,
"needYield" : 0,
"saveState" : 11384,
"restoreState" : 11384,
"isEOF" : 1,
"invalidates" : 0,
"inputStage" : {
"stage" : "FETCH",
"nReturned" : 354782,
"executionTimeMillisEstimate" : 219040,
"works" : 354783,
"advanced" : 354782,
"needTime" : 0,
"needYield" : 0,
"saveState" : 11383,
"restoreState" : 11383,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 354782,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 354782,
"executionTimeMillisEstimate" : 686,
"works" : 354783,
"advanced" : 354782,
"needTime" : 0,
"needYield" : 0,
"saveState" : 11383,
"restoreState" : 11383,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"indexedField" : 1
},
"indexName" : "indexedField_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"indexedField" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"indexedField" : [
"[1.0, 1.0]",
"[2.0, 2.0]"
]
},
"keysExamined" : 354782,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
}
},
"serverInfo" : {
"host" : "...",
"port" : 27017,
"version" : "3.4.4",
"gitVersion" : "888390515874a9debd1b6c5d36559ca86b44babd"
},
"ok" : 1
}
Any idea what is going wrong here?
You should be able to reproduce this by applying the following script to a Mongo installation.
Create a file create_test_database.js:
db.indexTestColl.createIndex({indexedField: 1});
var RECORDS_TO_CREATE = 5000000;
for (var i = 0; i < RECORDS_TO_CREATE; i++)
{
// Populate indexedField with random numbers [1 - 3].
db.indexTestColl.insertOne({"indexedField": NumberInt((Math.random() * 10) % 3 + 1)});
if ((i + 1) % 10000 == 0) print("Inserted " + (i + 1) + " documents.");
}
Create and populate the collection:
mongo localhost:27017/indexTestDb create_test_database.js
Then test it with these queries:
use indexTestDb
db.indexTestColl.explain("executionStats").count({indexedField: 1})
db.indexTestColl.explain("executionStats").count({indexedField: {$in: [1, 2]}})
db.indexTestColl.explain("executionStats").count({$or: [{indexedField: 1}, {indexedField: 2}] })
Am I correct in assuming that the $in and $or queries should benefit from the index being there?