mongodb text index not working - mongodb

mongo3.4.6
hi export, I am new to mongodb, and I have some problem with indexing. below I create a text index on RequestId(string) inside recordInfo collection:
db.getCollection("RecordInfo").createIndex({"RequestId":"text"})
but when I try to query below:
db.getCollection("RecordInfo").find({"RequestId":"4513456313212313212aaaa"}).explain("executionStats"), you can see it's not using index:
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 17,
"totalKeysExamined" : 0,
"totalDocsExamined" : 9998,
"executionStages" : {
"stage" : "COLLSCAN",
"filter" : {
"RequestId" : {
"$eq" : "4513456313212313212aaaa"
}
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 21,
"works" : 10000,
"advanced" : 1,
"needTime" : 9998,
"needYield" : 0,
"saveState" : 78,
"restoreState" : 78,
"isEOF" : 1,
"invalidates" : 0,
"direction" : "forward",
"docsExamined" : 9998
}
},
then I try below with $text:
db.getCollection("RecordInfo").find({$text:{$search:"4513456313212313212aaaa"}}).explain("executionStats")
it gives me below,which I think pretty good one:
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 1,
"totalKeysExamined" : 1,
"totalDocsExamined" : 1,
"executionStages" : {
"stage" : "TEXT",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 5,
"advanced" : 1,
"needTime" : 3,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"indexPrefix" : {
},
"indexName" : "RequestId_text",
"parsedTextQuery" : {
"terms" : [
"4513456313212313212aaaa"
],
"negatedTerms" : [ ],
"phrases" : [ ],
"negatedPhrases" : [ ]
},
"textIndexVersion" : 3,
"inputStage" : {
"stage" : "TEXT_MATCH",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 5,
"advanced" : 1,
"needTime" : 3,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"docsRejected" : 0,
"inputStage" : {
"stage" : "TEXT_OR",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 5,
"advanced" : 1,
"needTime" : 3,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 1,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 1,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"_fts" : "text",
"_ftsx" : 1
},
"indexName" : "RequestId_text",
"isMultiKey" : true,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "backward",
"indexBounds" : {
},
"keysExamined" : 1,
"seeks" : 1,
"dupsTested" : 1,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
}
},
but why mongo don't use a index by default, so I use hint to force a index query with below:
db.getCollection("RecordInfo").find({"RequestId":"4513456313212313212aaaa"}).hint("RequestId_text").explain("executionStats"), it give me these, which it's not that good:
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 93,
"totalKeysExamined" : 49378,
"totalDocsExamined" : 9998,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"RequestId" : {
"$eq" : "4513456313212313212aaaa"
}
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 91,
"works" : 49379,
"advanced" : 1,
"needTime" : 49377,
"needYield" : 0,
"saveState" : 386,
"restoreState" : 386,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 9998,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 9998,
"executionTimeMillisEstimate" : 50,
"works" : 49379,
"advanced" : 9998,
"needTime" : 39380,
"needYield" : 0,
"saveState" : 386,
"restoreState" : 386,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"_fts" : "text",
"_ftsx" : 1
},
"indexName" : "RequestId_text",
"isMultiKey" : true,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"_fts" : [
"[MinKey, MaxKey]"
],
"_ftsx" : [
"[MinKey, MaxKey]"
]
},
"keysExamined" : 49378,
"seeks" : 1,
"dupsTested" : 49378,
"dupsDropped" : 39380,
"seenInvalidated" : 0
}
}
},
To summaize, I want to use index or whatever method to query RequestId field which is string column fast. but if I force to use index, it seems not work for me only make my query worse. but if I use index another way, like below, I can see a pretty good query. but I can't specify on wich field I want to query this way.
db.getCollection("RecordInfo").find({$text:{$search:"4513456313212313212aaaa"}}).explain("executionStats")

Text search only works using the $text query operator.
When you execute db.getCollection("RecordInfo").find({"RequestId":"4513456313212313212aaaa"}), you're running a query for an exact match on that field.
From the question, it seems what you're looking for is a regular index, which you can create using db.getCollection("RecordInfo").createIndex({"RequestId": 1})
This will make your query using $text fail (because there is no text index) but will make the regular one use the index and avoid COLLSCAN.

Related

What is needTime on MongoDB cursor.explain("executionStats")?

I was checking that my query is optimum or not. For that I used Cursor.explain("executionStats"). At there few keys present which I am curious to know about.
So I found needTime. I researched on MongoDB Official Documentation but unfortunately, I was not able to understand. Is there anyone who help me out regarding this.
This is my result:
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"views" : 0,
},
"inputStage" : {
"stage" : "SORT",
"sortPattern" : {
"createdate" : -1
},
"limitAmount" : 20,
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"post_status" : {
"$eq" : 1
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"user_id" : 1,
"lastmodified" : -1
},
"indexName" : "user_id_1_lastmodified_-1",
"isMultiKey" : true,
"multiKeyPaths" : {
"user_id" : [ ],
"lastmodified" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"user_id" : [
"[MinKey, MaxKey]"
],
"lastmodified" : [
"[MaxKey, MinKey]"
]
}
}
}
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 20,
"executionTimeMillis" : 1,
"totalKeysExamined" : 386,
"totalDocsExamined" : 375,
"executionStages" : {
"stage" : "PROJECTION",
"nReturned" : 20,
"executionTimeMillisEstimate" : 0,
"works" : 409,
"advanced" : 20,
"needTime" : 388,
"needYield" : 0,
"saveState" : 3,
"restoreState" : 3,
"isEOF" : 1,
"invalidates" : 0,
"transformBy" : {
"views" : 0,
},
"inputStage" : {
"stage" : "SORT",
"nReturned" : 20,
"executionTimeMillisEstimate" : 0,
"works" : 409,
"advanced" : 20,
"needTime" : 388,
"needYield" : 0,
"saveState" : 3,
"restoreState" : 3,
"isEOF" : 1,
"invalidates" : 0,
"sortPattern" : {
"createdate" : -1
},
"memUsage" : 19348,
"memLimit" : 33554432,
"limitAmount" : 20,
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"nReturned" : 225,
"executionTimeMillisEstimate" : 0,
"works" : 388,
"advanced" : 225,
"needTime" : 162,
"needYield" : 0,
"saveState" : 3,
"restoreState" : 3,
"isEOF" : 1,
"invalidates" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"post_status" : {
"$eq" : 1
}
},
"nReturned" : 225,
"executionTimeMillisEstimate" : 0,
"works" : 387,
"advanced" : 225,
"needTime" : 161,
"needYield" : 0,
"saveState" : 3,
"restoreState" : 3,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 375,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 375,
"executionTimeMillisEstimate" : 0,
"works" : 387,
"advanced" : 375,
"needTime" : 11,
"needYield" : 0,
"saveState" : 3,
"restoreState" : 3,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"user_id" : 1,
"lastmodified" : -1
},
"indexName" : "user_id_1_lastmodified_-1",
"isMultiKey" : true,
"multiKeyPaths" : {
"user_id" : [ ],
"lastmodified" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"user_id" : [
"[MinKey, MaxKey]"
],
"lastmodified" : [
"[MaxKey, MinKey]"
]
},
"keysExamined" : 386,
"seeks" : 1,
"dupsTested" : 386,
"dupsDropped" : 11,
"seenInvalidated" : 0
}
}
}
}
}
},

How to query Mongodb on Single Field with multiple ranges efficiently?

I am trying to build custom geospatial indexes using MongoDB's B-tree indexes, as I find Mongo's native implementation limiting for my own case. In order to fulfill my geospatial queries which will effectively search Mongo using a compound index, I need to filter by the location.locIndexKey field with multiple ranges, among other fields.
So far, the only solution I could come up with to support this kind of queryies was using Mongo's $or operator. However, this performed badly since it's an or query and Mongo has to examine the same keys on the index again and again. In order to overcome this inefficiency, I need a way to make Mongo use multiple index-bounds on that field instead of replicating the query with or phrases for each defined bound in the query.
This is my query:
db.users.find({
"gender":2,
"preferences.feed.gender":1,
"age":{"$gte":18,"$lte":55},
"feedPrefChangeDay":{"$gte":1553461200,"$lte":1554066000},
"$or":[{"location.locIndexKey":{"$gte":NumberLong(1493233547543052300),"$lte":NumberLong(1493242343636074500)}},{"location.locIndexKey":{"$gte":NumberLong(1493242343636074500),"$lte":NumberLong(1493251139729096700)}},{"location.locIndexKey":{"$gte":NumberLong(1493287011295953000),"$lte":NumberLong(1493287148734906400)}}]
}).limit(20);
As you can see, in order to express multiple ranges on field location.locIndexKey, I had to use the $or operator. This is the shortened version of query planner's execution stats:
{
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 17762,
"totalKeysExamined" : 196192,
"totalDocsExamined" : 0,
"executionStages" : {
"stage" : "LIMIT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 351,
"works" : 196193,
"advanced" : 0,
"needTime" : 196191,
"needYield" : 0,
"saveState" : 19944,
"restoreState" : 19944,
"isEOF" : 1,
"invalidates" : 0,
"limitAmount" : 20,
"inputStage" : {
"stage" : "FETCH",
"nReturned" : 0,
"executionTimeMillisEstimate" : 351,
"works" : 196193,
"advanced" : 0,
"needTime" : 196191,
"needYield" : 0,
"saveState" : 19944,
"restoreState" : 19944,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 0,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "OR",
"nReturned" : 0,
"executionTimeMillisEstimate" : 351,
"works" : 196192,
"advanced" : 0,
"needTime" : 196191,
"needYield" : 0,
"saveState" : 19944,
"restoreState" : 19944,
"isEOF" : 1,
"invalidates" : 0,
"dupsTested" : 0,
"dupsDropped" : 0,
"recordIdsForgotten" : 0,
"inputStages" : [
{
"stage" : "IXSCAN",
"nReturned" : 0,
"executionTimeMillisEstimate" : 10,
"works" : 4534,
"advanced" : 0,
"needTime" : 4533,
"needYield" : 0,
"saveState" : 19944,
"restoreState" : 19944,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"gender" : 1.0,
"preferences.feed.gender" : 1.0,
"age" : 1.0,
"feedPrefChangeDay" : 1.0,
"location.locIndexKey" : 1.0
},
"indexName" : "gender_1_preferences.feed.gender_1_age_1_feedPrefChangeDay_1_location.locIndexKey_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"gender" : [],
"preferences.feed.gender" : [],
"age" : [],
"feedPrefChangeDay" : [],
"location.locIndexKey" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"gender" : [
"[2.0, 2.0]"
],
"preferences.feed.gender" : [
"[1.0, 1.0]"
],
"age" : [
"[18.0, 55.0]"
],
"feedPrefChangeDay" : [
"[1553461200.0, 1554066000.0]"
],
"location.locIndexKey" : [
"[1493569998101151700, 1493572197124407300]"
]
},
"keysExamined" : 4534,
"seeks" : 4534,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
},
{
"stage" : "IXSCAN",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 4534,
"advanced" : 0,
"needTime" : 4533,
"needYield" : 0,
"saveState" : 19944,
"restoreState" : 19944,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"gender" : 1.0,
"preferences.feed.gender" : 1.0,
"age" : 1.0,
"feedPrefChangeDay" : 1.0,
"location.locIndexKey" : 1.0
},
"indexName" : "gender_1_preferences.feed.gender_1_age_1_feedPrefChangeDay_1_location.locIndexKey_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"gender" : [],
"preferences.feed.gender" : [],
"age" : [],
"feedPrefChangeDay" : [],
"location.locIndexKey" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"gender" : [
"[2.0, 2.0]"
],
"preferences.feed.gender" : [
"[1.0, 1.0]"
],
"age" : [
"[18.0, 55.0]"
],
"feedPrefChangeDay" : [
"[1553461200.0, 1554066000.0]"
],
"location.locIndexKey" : [
"[1493587581697261600, 1493587590287196200]"
]
},
"keysExamined" : 4534,
"seeks" : 4534,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
},
{
"stage" : "IXSCAN",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 4534,
"advanced" : 0,
"needTime" : 4533,
"needYield" : 0,
"saveState" : 19944,
"restoreState" : 19944,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"gender" : 1.0,
"preferences.feed.gender" : 1.0,
"age" : 1.0,
"feedPrefChangeDay" : 1.0,
"location.locIndexKey" : 1.0
},
"indexName" : "gender_1_preferences.feed.gender_1_age_1_feedPrefChangeDay_1_location.locIndexKey_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"gender" : [],
"preferences.feed.gender" : [],
"age" : [],
"feedPrefChangeDay" : [],
"location.locIndexKey" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"gender" : [
"[2.0, 2.0]"
],
"preferences.feed.gender" : [
"[1.0, 1.0]"
],
"age" : [
"[18.0, 55.0]"
],
"feedPrefChangeDay" : [
"[1553461200.0, 1554066000.0]"
],
"location.locIndexKey" : [
"[1493981215449940000, 1493990011542962200]"
]
},
"keysExamined" : 4534,
"seeks" : 4534,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
If you check indexBounds above, you will see that each range for location.locIndexKey is applied to a single query and combined with or. However, if I choose to run the same query using Mongo's native geospatial operator $geoWithin:
db.users.find({
"gender" : 2.0,
"preferences.feed.gender" : 1.0,
"age" : {
"$gte" : 18.0,
"$lte" : 55.0
},
"feedPrefChangeDay" : {
"$gte" : 1553461200.0,
"$lte" : 1554066000.0
},
"location.loc" : {
"$geoWithin" : {
"$centerSphere" : [
[
0.0,
0.0
],
0.00784806152880239
]
}
}
}).limit(20);
I get the following response from the query planner:
{
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 7,
"totalKeysExamined" : 4506,
"totalDocsExamined" : 0,
"executionStages" : {
"stage" : "LIMIT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 4506,
"advanced" : 0,
"needTime" : 4505,
"needYield" : 0,
"saveState" : 35,
"restoreState" : 35,
"isEOF" : 1,
"invalidates" : 0,
"limitAmount" : 20,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"location.loc" : {
"$geoWithin" : {
"$centerSphere" : [
[
0.0,
0.0
],
0.00784806152880239
]
}
}
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 4506,
"advanced" : 0,
"needTime" : 4505,
"needYield" : 0,
"saveState" : 35,
"restoreState" : 35,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 0,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 4506,
"advanced" : 0,
"needTime" : 4505,
"needYield" : 0,
"saveState" : 35,
"restoreState" : 35,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"gender" : 1.0,
"preferences.feed.gender" : 1.0,
"age" : 1.0,
"feedPrefChangeDay" : 1.0,
"location.loc" : "2dsphere"
},
"indexName" : "gender_1_preferences.feed.gender_1_age_1_feedPrefChangeDay_1_location.loc_2dsphere",
"isMultiKey" : false,
"multiKeyPaths" : {
"gender" : [],
"preferences.feed.gender" : [],
"age" : [],
"feedPrefChangeDay" : [],
"location.loc" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"gender" : [
"[2.0, 2.0]"
],
"preferences.feed.gender" : [
"[1.0, 1.0]"
],
"age" : [
"[18.0, 55.0]"
],
"feedPrefChangeDay" : [
"[1553461200.0, 1554066000.0]"
],
"location.loc" : [
"[360287970189639680, 360287970189639680]",
"[378302368699121664, 378302368699121664]",
"[382805968326492160, 382805968326492160]",
"[383931868233334784, 383931868233334784]",
"[384213343210045440, 384213343210045440]",
"[384230935396089856, 384230935396089856]",
"[384235333442600960, 384235333442600960]",
"[384236432954228736, 384236432954228736]",
"[384236432954228737, 384236982710042623]",
"[384266119768178688, 384266119768178688]",
"[384266119768178689, 384274915861200895]",
"[384274915861200897, 384283711954223103]",
"[384283711954223104, 384283711954223104]",
"[384283711954223105, 384318896326311935]",
"[384318896326311937, 384354080698400767]",
"[1080863910568919040, 1080863910568919040]",
"[1134907106097364992, 1134907106097364992]",
"[1148417904979476480, 1148417904979476480]",
"[1151795604700004352, 1151795604700004352]",
"[1152640029630136320, 1152640029630136320]",
"[1152789563211513857, 1152798359304536063]",
"[1152798359304536064, 1152798359304536064]",
"[1152798359304536065, 1152807155397558271]",
"[1152833543676624896, 1152833543676624896]",
"[1152846737816158208, 1152846737816158208]",
"[1152850036351041536, 1152850036351041536]",
"[1152850586106855425, 1152851135862669311]",
"[1152851135862669312, 1152851135862669312]",
"[1152851135862669313, 1152859931955691519]",
"[1152868728048713728, 1152868728048713728]",
"[1152877524141735937, 1152886320234758143]",
"[1152886320234758145, 1152921504606846975]",
"[1152921504606846977, 1152956688978935807]",
"[1152956688978935809, 1152991873351024639]",
"[1152991873351024640, 1152991873351024640]",
"[1152991873351024641, 1152992423106838527]",
"[1152992972862652416, 1152992972862652416]",
"[1152996271397535744, 1152996271397535744]",
"[1153009465537069056, 1153009465537069056]",
"[1153035853816135681, 1153044649909157887]",
"[1153044649909157888, 1153044649909157888]",
"[1153044649909157889, 1153053446002180095]",
"[1153202979583557632, 1153202979583557632]",
"[1154047404513689600, 1154047404513689600]",
"[1157425104234217472, 1157425104234217472]",
"[1170935903116328960, 1170935903116328960]",
"[1224979098644774912, 1224979098644774912]",
"[1921488928515293185, 1921524112887382015]",
"[1921524112887382017, 1921559297259470847]",
"[1921559297259470848, 1921559297259470848]",
"[1921559297259470849, 1921594481631559679]",
"[1921606026503651329, 1921606576259465215]",
"[1921606576259465216, 1921606576259465216]",
"[1921607675771092992, 1921607675771092992]",
"[1921612073817604096, 1921612073817604096]",
"[1921629666003648512, 1921629666003648512]",
"[1921911140980359168, 1921911140980359168]",
"[1923037040887201792, 1923037040887201792]",
"[1927540640514572288, 1927540640514572288]",
"[1945555039024054272, 1945555039024054272]"
]
},
"keysExamined" : 4506,
"seeks" : 4506,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
}
As you can see, Mongo takes advantage of multiple index bounds to fulfill this query and its much more effective.
I believe the inefficiency in the original query happens because Mongo's query planner doesn't check what's inside the $or expression. I think that it should be more clever to understand that there is just one field with multiple ranges inside the expression and build the query using multiple index bounds. Sadly, this is not the case.
My question: is there any way that I can force Mongo to use multiple index bounds for my query, so that it's as efficient as the native geospatial query?
Any help would be appreciated.
Thanks!

MongoDB uses wrong index, even after clearing the query plan cache

I have the following command:
db.mycol.find({sourceId:ObjectId("596bac5a6f473e1a042bFFFF"),myFlag:false}).count()
It was taking a lot of time.
So I decided to add an index { "sourceId" : -1, "myFlag" : -1 }
MongoDB still kept taking the same time.
When I ran explain() on the find command, I noticed that mongoDB still kept using my old indexes.
db.mycol.find({sourceId:ObjectId("596bac5a6f473e1a042bFFFF"),myFlag:false}).explain(true)
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "mydb.mycol",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"sourceId" : {
"$eq" : ObjectId("596bac5a6f473e1a042bFFFF")
}
},
{
"myFlag" : {
"$eq" : false
}
}
]
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"myFlag" : {
"$eq" : false
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"sourceId" : 1
},
"indexName" : "sourceId_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"sourceId" : [
"[ObjectId('596bac5a6f473e1a042bFFFF'), ObjectId('596bac5a6f473e1a042bFFFF')]"
]
}
}
},
"rejectedPlans" : [
{
"stage" : "FETCH",
"filter" : {
"sourceId" : {
"$eq" : ObjectId("596bac5a6f473e1a042bFFFF")
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"myFlag" : -1
},
"indexName" : "myFlag_-1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"myFlag" : [
"[false, false]"
]
}
}
},
{
"stage" : "FETCH",
"filter" : {
"myFlag" : {
"$eq" : false
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"sourceId" : -1,
"timestamp" : -1
},
"indexName" : "sourceId_-1_timestamp_-1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"sourceId" : [
"[ObjectId('596bac5a6f473e1a042bFFFF'), ObjectId('596bac5a6f473e1a042bFFFF')]"
],
"timestamp" : [
"[MaxKey, MinKey]"
]
}
}
},
{
"stage" : "FETCH",
"filter" : {
"myFlag" : {
"$eq" : false
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"sourceId" : -1,
"timestamp" : 1
},
"indexName" : "sourceId_-1_timestamp_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"sourceId" : [
"[ObjectId('596bac5a6f473e1a042bFFFF'), ObjectId('596bac5a6f473e1a042bFFFF')]"
],
"timestamp" : [
"[MinKey, MaxKey]"
]
}
}
},
{
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"sourceId" : -1,
"myFlag" : -1
},
"indexName" : "sourceId_-1_myFlag_-1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"sourceId" : [
"[ObjectId('596bac5a6f473e1a042bFFFF'), ObjectId('596bac5a6f473e1a042bFFFF')]"
],
"myFlag" : [
"[false, false]"
]
}
}
}
]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 2074,
"executionTimeMillis" : 33936,
"totalKeysExamined" : 2074,
"totalDocsExamined" : 2074,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"myFlag" : {
"$eq" : false
}
},
"nReturned" : 2074,
"executionTimeMillisEstimate" : 31710,
"works" : 2075,
"advanced" : 2074,
"needTime" : 0,
"needYield" : 0,
"saveState" : 1554,
"restoreState" : 1554,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 2074,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 2074,
"executionTimeMillisEstimate" : 0,
"works" : 2075,
"advanced" : 2074,
"needTime" : 0,
"needYield" : 0,
"saveState" : 1554,
"restoreState" : 1554,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"sourceId" : 1
},
"indexName" : "sourceId_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"sourceId" : [
"[ObjectId('596bac5a6f473e1a042bFFFF'), ObjectId('596bac5a6f473e1a042bFFFF')]"
]
},
"keysExamined" : 2074,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
},
"allPlansExecution" : [
{
"nReturned" : 0,
"executionTimeMillisEstimate" : 1630,
"totalKeysExamined" : 101,
"totalDocsExamined" : 101,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"sourceId" : {
"$eq" : ObjectId("596bac5a6f473e1a042bFFFF")
}
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 1630,
"works" : 101,
"advanced" : 0,
"needTime" : 101,
"needYield" : 0,
"saveState" : 1554,
"restoreState" : 1554,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 101,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 1554,
"restoreState" : 1554,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"myFlag" : -1
},
"indexName" : "myFlag_-1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"myFlag" : [
"[false, false]"
]
},
"keysExamined" : 101,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
{
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"totalKeysExamined" : 101,
"totalDocsExamined" : 101,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"myFlag" : {
"$eq" : false
}
},
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 1554,
"restoreState" : 1554,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 101,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 1554,
"restoreState" : 1554,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"sourceId" : -1,
"timestamp" : -1
},
"indexName" : "sourceId_-1_timestamp_-1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"sourceId" : [
"[ObjectId('596bac5a6f473e1a042bFFFF'), ObjectId('596bac5a6f473e1a042bFFFF')]"
],
"timestamp" : [
"[MaxKey, MinKey]"
]
},
"keysExamined" : 101,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
{
"nReturned" : 101,
"executionTimeMillisEstimate" : 10,
"totalKeysExamined" : 101,
"totalDocsExamined" : 101,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"myFlag" : {
"$eq" : false
}
},
"nReturned" : 101,
"executionTimeMillisEstimate" : 10,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 1554,
"restoreState" : 1554,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 101,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 1554,
"restoreState" : 1554,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"sourceId" : -1,
"timestamp" : 1
},
"indexName" : "sourceId_-1_timestamp_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"sourceId" : [
"[ObjectId('596bac5a6f473e1a042bFFFF'), ObjectId('596bac5a6f473e1a042bFFFF')]"
],
"timestamp" : [
"[MinKey, MaxKey]"
]
},
"keysExamined" : 101,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
{
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"totalKeysExamined" : 101,
"totalDocsExamined" : 101,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 1554,
"restoreState" : 1554,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 101,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 1554,
"restoreState" : 1554,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"sourceId" : -1,
"myFlag" : -1
},
"indexName" : "sourceId_-1_myFlag_-1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"sourceId" : [
"[ObjectId('596bac5a6f473e1a042bFFFF'), ObjectId('596bac5a6f473e1a042bFFFF')]"
],
"myFlag" : [
"[false, false]"
]
},
"keysExamined" : 101,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
{
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"totalKeysExamined" : 101,
"totalDocsExamined" : 101,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"myFlag" : {
"$eq" : false
}
},
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 88,
"restoreState" : 88,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 101,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 101,
"executionTimeMillisEstimate" : 0,
"works" : 101,
"advanced" : 101,
"needTime" : 0,
"needYield" : 0,
"saveState" : 88,
"restoreState" : 88,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"sourceId" : 1
},
"indexName" : "sourceId_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"sourceId" : [
"[ObjectId('596bac5a6f473e1a042bFFFF'), ObjectId('596bac5a6f473e1a042bFFFF')]"
]
},
"keysExamined" : 101,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
]
},
"serverInfo" : {
"host" : "gdm3d",
"port" : 27017,
"version" : "3.2.15",
"gitVersion" : "e11e3c1b9c9ce3f7b4a79493e16f5e4504e01140"
},
"ok" : 1
}
For some reason, it rejects the plan to use sourceId_-1_myFlag_-1 and goes with sourceId_1 and then filters myFlag document by document.
When I forced it to use the index, it returned the result immediately!
db.mycol.find({sourceId:ObjectId("596bac5a6f473e1a042bFFFF"),myFlag:false}).hint("sourceId_-1_myFlag_-1").count()
I read that periodically mongoDB runs all the plans and checks which one is faster, then uses that one in future.
I even tried restarting the mongodb, clearing query plan cache, restarting the computer. For some sourceIds with very less data, it did use the correct index automatically (I checked the index usage) but then it again started using the old ones.
I don't want to force it to use the index. How do I make sure it automatically does that?
Update:
It started using the correct one after some time. Atleast thats what the indexStats says.
However, the command still takes time, and when i give it hint, it gives output immediately.

How to improve mongo queries with multikey index in array

I just found out that 1 of our queries is quite slow. We use a multikey index in an array and not sure how we can actually improve this query.
Our data structure:
account: [{
accountId:string,
service:string
}]
Index key is:
{"account.accountId":1, "account.service":1}
Here's my query:
db.model.find({"account.accountId":"12345", "account.service":"GameCenter"}).explain();
executionStats (1 million records)
"executionStats" : {
"nReturned" : 1,
"executionTimeMillis" : 325,
"totalKeysExamined" : 122744,
"totalDocsExamined" : 122743,
"executionStages" : {
"stage" : "SHARD_MERGE",
"nReturned" : 1,
"executionTimeMillis" : 325,
"totalKeysExamined" : 122744,
"totalDocsExamined" : 122743,
"totalChildMillis" : NumberLong(834),
"shards" : [
{
"shardName" : "rs1",
"executionSuccess" : true,
"executionStages" : {
"stage" : "SHARDING_FILTER",
"nReturned" : 0,
"executionTimeMillisEstimate" : 300,
"works" : 40999,
"advanced" : 0,
"needTime" : 40998,
"needYield" : 0,
"saveState" : 320,
"restoreState" : 320,
"isEOF" : 1,
"invalidates" : 0,
"chunkSkips" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"account.accountId" : {
"$eq" : "G:8183971619"
}
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 300,
"works" : 40999,
"advanced" : 0,
"needTime" : 40998,
"needYield" : 0,
"saveState" : 320,
"restoreState" : 320,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 40998,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 40998,
"executionTimeMillisEstimate" : 30,
"works" : 40999,
"advanced" : 40998,
"needTime" : 0,
"needYield" : 0,
"saveState" : 320,
"restoreState" : 320,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"account.service" : 1,
"account.accountId" : 1
},
"indexName" : "account.service_1_account.accountId_1",
"isMultiKey" : true,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"account.service" : [
"[\"GameCenter\", \"GameCenter\"]"
],
"account.accountId" : [
"[MinKey, MaxKey]"
]
},
"keysExamined" : 40998,
"dupsTested" : 40998,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
},
{
"shardName" : "rs2",
"executionSuccess" : true,
"executionStages" : {
"stage" : "SHARDING_FILTER",
"nReturned" : 1,
"executionTimeMillisEstimate" : 240,
"works" : 40612,
"advanced" : 1,
"needTime" : 40610,
"needYield" : 0,
"saveState" : 317,
"restoreState" : 317,
"isEOF" : 1,
"invalidates" : 0,
"chunkSkips" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"account.accountId" : {
"$eq" : "G:8183971619"
}
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 230,
"works" : 40612,
"advanced" : 1,
"needTime" : 40610,
"needYield" : 0,
"saveState" : 317,
"restoreState" : 317,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 40610,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 40611,
"executionTimeMillisEstimate" : 70,
"works" : 40612,
"advanced" : 40611,
"needTime" : 0,
"needYield" : 0,
"saveState" : 317,
"restoreState" : 317,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"account.service" : 1,
"account.accountId" : 1
},
"indexName" : "account.service_1_account.accountId_1",
"isMultiKey" : true,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"account.service" : [
"[\"GameCenter\", \"GameCenter\"]"
],
"account.accountId" : [
"[MinKey, MaxKey]"
]
},
"keysExamined" : 40611,
"dupsTested" : 40611,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
},
{
"shardName" : "rs3",
"executionSuccess" : true,
"executionStages" : {
"stage" : "SHARDING_FILTER",
"nReturned" : 0,
"executionTimeMillisEstimate" : 270,
"works" : 41136,
"advanced" : 0,
"needTime" : 41135,
"needYield" : 0,
"saveState" : 321,
"restoreState" : 321,
"isEOF" : 1,
"invalidates" : 0,
"chunkSkips" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"account.accountId" : {
"$eq" : "G:8183971619"
}
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 270,
"works" : 41136,
"advanced" : 0,
"needTime" : 41135,
"needYield" : 0,
"saveState" : 321,
"restoreState" : 321,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 41135,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 41135,
"executionTimeMillisEstimate" : 90,
"works" : 41136,
"advanced" : 41135,
"needTime" : 0,
"needYield" : 0,
"saveState" : 321,
"restoreState" : 321,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"account.service" : 1,
"account.accountId" : 1
},
"indexName" : "account.service_1_account.accountId_1",
"isMultiKey" : true,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"account.service" : [
"[\"GameCenter\", \"GameCenter\"]"
],
"account.accountId" : [
"[MinKey, MaxKey]"
]
},
"keysExamined" : 41135,
"dupsTested" : 41135,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
}
]
}
},
To summarise, the query do use the indexes but scan a lot of documents to get the results (122k / 1million). We couldn't use covered index as we need to return some other information too.
Also something werid: I'm querying for a unique accoundId, but my indexBounds for account.accountId is:
"account.accountId" : [
"[MinKey, MaxKey]"
]
Thank you for your help!
Mars
After reading the executionStatus carefully, the query is actually scanning all indexes since "accountId" indexBounds is [MinKey, MaxKey].
I'm able to resolve this issue with $elemMatch
db.model.find({
account:{
$elemMatch:{
accountId:"111",
service:"facebook"
}
}
})

Similar queries to different collections have vastly different performance

This query takes 66 seconds:
{
"op" : "query",
"ns" : "pipelines_odd.CachedUrl_319",
"query" : {
"find" : "CachedUrl_319",
"filter" : {
"$and" : [
{
"updated_at" : {
"$lt" : ISODate("2016-03-23T19:26:36.207Z")
}
},
{
"host_pattern_id" : 1844
}
]
},
"ntoreturn" : 100,
"sort" : {
"updated_at" : 1
}
},
"keysExamined" : 0,
"docsExamined" : 0,
"hasSortStage" : true,
"cursorExhausted" : true,
"keyUpdates" : 0,
"writeConflicts" : 0,
"numYield" : 18150,
"locks" : {
"Global" : {
"acquireCount" : {
"r" : NumberLong(36302)
},
"acquireWaitCount" : {
"r" : NumberLong(3078)
},
"timeAcquiringMicros" : {
"r" : NumberLong(3054408)
}
},
"Database" : {
"acquireCount" : {
"r" : NumberLong(18151)
}
},
"Collection" : {
"acquireCount" : {
"r" : NumberLong(18151)
}
}
},
"nreturned" : 0,
"responseLength" : 20,
"millis" : 66576,
"execStats" : {
"stage" : "ENSURE_SORTED",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 6,
"advanced" : 0,
"needTime" : 5,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"nDropped" : 0,
"inputStage" : {
"stage" : "OR",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 6,
"advanced" : 0,
"needTime" : 5,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"dupsTested" : 0,
"dupsDropped" : 0,
"locsForgotten" : 0,
"inputStages" : [
{
"stage" : "SORT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 3,
"advanced" : 0,
"needTime" : 2,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"sortPattern" : {
"updated_at" : 1
},
"memUsage" : 0,
"memLimit" : 33554432,
"limitAmount" : 100,
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 0,
"needTime" : 1,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"updated_at" : {
"$lt" : ISODate("2016-03-23T19:26:36.207Z")
}
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 0,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"host_pattern_id" : 1
},
"indexName" : "host_pattern_id_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"host_pattern_id" : [
"[1844, 1844]"
]
},
"keysExamined" : 0,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
},
{
"stage" : "SORT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 3,
"advanced" : 0,
"needTime" : 2,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"sortPattern" : {
"updated_at" : 1
},
"memUsage" : 0,
"memLimit" : 33554432,
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 0,
"needTime" : 1,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"updated_at" : {
"$lt" : ISODate("2016-03-23T19:26:36.207Z")
}
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 0,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"host_pattern_id" : 1
},
"indexName" : "host_pattern_id_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"host_pattern_id" : [
"[1844, 1844]"
]
},
"keysExamined" : 0,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
}
]
}
},
"ts" : ISODate("2016-03-30T19:27:56.347Z"),
"allUsers" : [ ],
"user" : ""
}
While a similar query against a different collection of about the same size runs in 10 milliseconds:
{
"op" : "query",
"ns" : "pipelines_odd.CachedUrl_257",
"query" : {
"find" : "CachedUrl_257",
"filter" : {
"$or" : [
{
"$and" : [
{
"updated_at" : {
"$lt" : ISODate("2016-01-23T20:55:52.174Z")
}
},
{
"host_pattern_id" : 5046
}
]
}
]
},
"ntoreturn" : 100,
"sort" : {
"updated_at" : 1
}
},
"cursorid" : NumberLong("16448827549027"),
"keysExamined" : 100,
"docsExamined" : 100,
"keyUpdates" : 0,
"writeConflicts" : 0,
"numYield" : 1,
"locks" : {
"Global" : {
"acquireCount" : {
"r" : NumberLong(4)
}
},
"Database" : {
"acquireCount" : {
"r" : NumberLong(2)
}
},
"Collection" : {
"acquireCount" : {
"r" : NumberLong(2)
}
}
},
"nreturned" : 100,
"responseLength" : 42183,
"millis" : 10,
"execStats" : {
"stage" : "CACHED_PLAN",
"nReturned" : 100,
"executionTimeMillisEstimate" : 10,
"works" : 100,
"advanced" : 100,
"needTime" : 0,
"needYield" : 0,
"saveState" : 2,
"restoreState" : 1,
"isEOF" : 0,
"invalidates" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"host_pattern_id" : {
"$eq" : 5046
}
},
"nReturned" : 100,
"executionTimeMillisEstimate" : 10,
"works" : 100,
"advanced" : 100,
"needTime" : 0,
"needYield" : 0,
"saveState" : 2,
"restoreState" : 1,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 100,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 100,
"executionTimeMillisEstimate" : 0,
"works" : 100,
"advanced" : 100,
"needTime" : 0,
"needYield" : 0,
"saveState" : 2,
"restoreState" : 1,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"updated_at" : 1
},
"indexName" : "updated_at_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"updated_at" : [
"(true, new Date(1453582552174))"
]
},
"keysExamined" : 100,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"ts" : ISODate("2016-03-23T20:55:40.203Z"),
"allUsers" : [ ],
"user" : ""
}
Both collections have similar sizes and the same indexes:
PipelinesCluster1:SECONDARY> db.CachedUrl_319.count()
24383730
PipelinesCluster1:SECONDARY> db.CachedUrl_319.getIndexes()
[
{
"ns" : "pipelines_odd.CachedUrl_319",
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"ns" : "pipelines_odd.CachedUrl_319",
"v" : 1,
"key" : {
"updated_at" : 1
},
"name" : "updated_at_1",
"background" : true
},
{
"ns" : "pipelines_odd.CachedUrl_319",
"v" : 1,
"key" : {
"host_pattern_id" : 1
},
"name" : "host_pattern_id_1",
"background" : true
}
]
PipelinesCluster1:SECONDARY> db.CachedUrl_257.count()
24697281
PipelinesCluster1:SECONDARY> db.CachedUrl_257.getIndexes()
[
{
"ns" : "pipelines_odd.CachedUrl_257",
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"ns" : "pipelines_odd.CachedUrl_257",
"v" : 1,
"key" : {
"updated_at" : 1
},
"name" : "updated_at_1",
"background" : true
},
{
"ns" : "pipelines_odd.CachedUrl_257",
"v" : 1,
"key" : {
"host_pattern_id" : 1
},
"name" : "host_pattern_id_1",
"background" : true
}
]
I understand that query performance can vary depending on database load and other factors, but the queries against CachedUrl_319 are consistently slow, while those against CachedUrl_257 are always returned instantly. What could be causing that and is there any way to fix it?
I think you were cached for your second query.
You created an index, so mongodb automatically handled caching for you.
FAQs # mongodb.org
If you look at the second system.profile collection you posted, in the execStats
"execStats" : {
"stage" : "CACHED_PLAN", <-- you were cached
Compare it to the first one, and you will see that the first system.profile collection has different stages, e.g.
"execStats" : {
"stage" : "ENSURE_SORTED"
You can also look at the "inputStage" , and you will see the second one just fetches.
"inputStage" : {
"stage" : "FETCH",
And the first one does more work, e.g. "SORT" and "SORT_KEY_GENERATOR".