The data I’m testing with is a _User
collection with about 4.4 million users. One of the users has an email
of robby@pocketprep.com
. I have two indexes on email
: a case-insensitive one called case_insensitive_email
and a case-sensitive one called email_1
.
Explain Output Without Hint
- indexName:
case_insensitive_email
- executionTimeMillis: 7718
db.getCollection('_User').find({ email: { $regex: /^Robby@pocketprep\.com$/i } }).explain("allPlansExecution")
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "pocketprep._User",
"indexFilterSet" : false,
"parsedQuery" : {
"email" : {
"$regex" : "^Robby@pocketprep\\.com$",
"$options" : "i"
}
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"email" : {
"$regex" : "^Robby@pocketprep\\.com$",
"$options" : "i"
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"email" : 1
},
"indexName" : "case_insensitive_email",
"collation" : {
"locale" : "en_US",
"caseLevel" : false,
"caseFirst" : "off",
"strength" : 2,
"numericOrdering" : false,
"alternate" : "non-ignorable",
"maxVariable" : "punct",
"normalization" : false,
"backwards" : false,
"version" : "57.1"
},
"isMultiKey" : false,
"multiKeyPaths" : {
"email" : [ ]
},
"isUnique" : false,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"email" : [
"[\"\", {})",
"[/^Robby@pocketprep\\.com$/i, /^Robby@pocketprep\\.com$/i]"
]
}
}
},
"rejectedPlans" : [
{
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"filter" : {
"email" : {
"$regex" : "^Robby@pocketprep\\.com$",
"$options" : "i"
}
},
"keyPattern" : {
"email" : 1
},
"indexName" : "email_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"email" : [ ]
},
"isUnique" : true,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"email" : [
"[\"\", {})",
"[/^Robby@pocketprep\\.com$/i, /^Robby@pocketprep\\.com$/i]"
]
}
}
}
]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 7718,
"totalKeysExamined" : 1902678,
"totalDocsExamined" : 1902678,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"email" : {
"$regex" : "^Robby@pocketprep\\.com$",
"$options" : "i"
}
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 6030,
"works" : 1902679,
"advanced" : 1,
"needTime" : 1902677,
"needYield" : 0,
"saveState" : 25181,
"restoreState" : 25181,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 1902678,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1902678,
"executionTimeMillisEstimate" : 1170,
"works" : 1902679,
"advanced" : 1902678,
"needTime" : 0,
"needYield" : 0,
"saveState" : 25181,
"restoreState" : 25181,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"email" : 1
},
"indexName" : "case_insensitive_email",
"collation" : {
"locale" : "en_US",
"caseLevel" : false,
"caseFirst" : "off",
"strength" : 2,
"numericOrdering" : false,
"alternate" : "non-ignorable",
"maxVariable" : "punct",
"normalization" : false,
"backwards" : false,
"version" : "57.1"
},
"isMultiKey" : false,
"multiKeyPaths" : {
"email" : [ ]
},
"isUnique" : false,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"email" : [
"[\"\", {})",
"[/^Robby@pocketprep\\.com$/i, /^Robby@pocketprep\\.com$/i]"
]
},
"keysExamined" : 1902678,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
},
"allPlansExecution" : [
{
"nReturned" : 0,
"executionTimeMillisEstimate" : 1340,
"totalKeysExamined" : 1320493,
"totalDocsExamined" : 0,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 0,
"executionTimeMillisEstimate" : 1340,
"works" : 1320493,
"advanced" : 0,
"needTime" : 1320493,
"needYield" : 0,
"saveState" : 20632,
"restoreState" : 20632,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 0,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"filter" : {
"email" : {
"$regex" : "^Robby@pocketprep\\.com$",
"$options" : "i"
}
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 1290,
"works" : 1320493,
"advanced" : 0,
"needTime" : 1320493,
"needYield" : 0,
"saveState" : 20632,
"restoreState" : 20632,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"email" : 1
},
"indexName" : "email_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"email" : [ ]
},
"isUnique" : true,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"email" : [
"[\"\", {})",
"[/^Robby@pocketprep\\.com$/i, /^Robby@pocketprep\\.com$/i]"
]
},
"keysExamined" : 1320493,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
{
"nReturned" : 0,
"executionTimeMillisEstimate" : 4130,
"totalKeysExamined" : 1320493,
"totalDocsExamined" : 1320493,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"email" : {
"$regex" : "^Robby@pocketprep\\.com$",
"$options" : "i"
}
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 4130,
"works" : 1320493,
"advanced" : 0,
"needTime" : 1320493,
"needYield" : 0,
"saveState" : 20632,
"restoreState" : 20632,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 1320493,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1320493,
"executionTimeMillisEstimate" : 790,
"works" : 1320493,
"advanced" : 1320493,
"needTime" : 0,
"needYield" : 0,
"saveState" : 20632,
"restoreState" : 20632,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"email" : 1
},
"indexName" : "case_insensitive_email",
"collation" : {
"locale" : "en_US",
"caseLevel" : false,
"caseFirst" : "off",
"strength" : 2,
"numericOrdering" : false,
"alternate" : "non-ignorable",
"maxVariable" : "punct",
"normalization" : false,
"backwards" : false,
"version" : "57.1"
},
"isMultiKey" : false,
"multiKeyPaths" : {
"email" : [ ]
},
"isUnique" : false,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"email" : [
"[\"\", {})",
"[/^Robby@pocketprep\\.com$/i, /^Robby@pocketprep\\.com$/i]"
]
},
"keysExamined" : 1320493,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
]
},
"serverInfo" : {
"host" : "h083332.mongolab.com",
"port" : 31949,
"version" : "3.6.12",
"gitVersion" : "c2b9acad0248ca06b14ef1640734b5d0595b55f1"
},
"ok" : 1,
"operationTime" : Timestamp(1585918338, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1585918338, 1),
"signature" : {
"hash" : BinData(0,"Wrc5pfaJ6T92PVv8AR+NwoZQTWo="),
"keyId" : NumberLong("6768738634519543813")
}
}
}
Explain Output With Hint
- indexName:
email_1
- executionTimeMillis: 1405
db.getCollection('_User').find({ email: { $regex: /^Robby@pocketprep\.com$/i } }).hint("email_1").explain("allPlansExecution")
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "pocketprep._User",
"indexFilterSet" : false,
"parsedQuery" : {
"email" : {
"$regex" : "^Robby@pocketprep\\.com$",
"$options" : "i"
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"filter" : {
"email" : {
"$regex" : "^Robby@pocketprep\\.com$",
"$options" : "i"
}
},
"keyPattern" : {
"email" : 1
},
"indexName" : "email_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"email" : [ ]
},
"isUnique" : true,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"email" : [
"[\"\", {})",
"[/^Robby@pocketprep\\.com$/i, /^Robby@pocketprep\\.com$/i]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 1405,
"totalKeysExamined" : 1902678,
"totalDocsExamined" : 1,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 1,
"executionTimeMillisEstimate" : 1293,
"works" : 1902679,
"advanced" : 1,
"needTime" : 1902677,
"needYield" : 0,
"saveState" : 14864,
"restoreState" : 14864,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 1,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"filter" : {
"email" : {
"$regex" : "^Robby@pocketprep\\.com$",
"$options" : "i"
}
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 1233,
"works" : 1902679,
"advanced" : 1,
"needTime" : 1902677,
"needYield" : 0,
"saveState" : 14864,
"restoreState" : 14864,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"email" : 1
},
"indexName" : "email_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"email" : [ ]
},
"isUnique" : true,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"email" : [
"[\"\", {})",
"[/^Robby@pocketprep\\.com$/i, /^Robby@pocketprep\\.com$/i]"
]
},
"keysExamined" : 1902678,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
},
"allPlansExecution" : [ ]
},
"serverInfo" : {
"host" : "h083332.mongolab.com",
"port" : 31949,
"version" : "3.6.12",
"gitVersion" : "c2b9acad0248ca06b14ef1640734b5d0595b55f1"
},
"ok" : 1,
"operationTime" : Timestamp(1585918753, 305),
"$clusterTime" : {
"clusterTime" : Timestamp(1585918753, 305),
"signature" : {
"hash" : BinData(0,"y1dKXHvMsn/J6ApjvkRg8UHXe1E="),
"keyId" : NumberLong("6768738634519543813")
}
}
}
So, yes, we can improve the request time by providing the hint
, but I’m very confused as to why the query optimizer would be selecting the index that results in a request that is 5.5x slower in this case.
Appreciate your help and input! Thanks.