MongoDB multikey index performance - mongodb

Background
I have a collection of users with structure of documents like this:
{
"_id" : ObjectId("54e61137cca5d2ff0a8b4567"),
"login" : "test1",
"emails" : [
{
"email" : "test1#example.com",
"is_primary" : true,
"_id" : ObjectId("57baf3e97323afb2688e639c")
},
{
"email" : "test1_1#example.com",
"is_primary" : false,
"_id" : ObjectId("57baf3e97323afb2688e639d")
}
]
}
Indexes:
{
"v" : 1,
"key" : {
"login" : 1
},
"name" : "login_1",
"ns" : "mydb.users",
"background" : true
},
{
"v" : 1,
"key" : {
"emails.email" : 1
},
"name" : "emails.email_1",
"ns" : "mydb.users"
}
Count of documents is ~700000
Scenario
To explain the search of users by login, I make this:
rs0:PRIMARY> db.users.explain('executionStats').find({'login' : /test123123123/})
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "mydb.users",
"indexFilterSet" : false,
"parsedQuery" : {
"login" : /test123123123/
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"filter" : {
"login" : /test123123123/
},
"keyPattern" : {
"login" : 1
},
"indexName" : "login_1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"login" : [
"[\"\", {})",
"[/test123123123/, /test123123123/]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 1040,
"totalKeysExamined" : 698993,
"totalDocsExamined" : 0,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 0,
"executionTimeMillisEstimate" : 930,
"works" : 698994,
"advanced" : 0,
"needTime" : 698993,
"needFetch" : 0,
"saveState" : 5460,
"restoreState" : 5460,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 0,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"filter" : {
"login" : /test123123123/
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 920,
"works" : 698993,
"advanced" : 0,
"needTime" : 698993,
"needFetch" : 0,
"saveState" : 5460,
"restoreState" : 5460,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"login" : 1
},
"indexName" : "login_1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"login" : [
"[\"\", {})",
"[/test123123123/, /test123123123/]"
]
},
"keysExamined" : 698993,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0
}
}
},
"serverInfo" : {
"host" : "myhost",
"port" : 27017,
"version" : "3.0.12",
"gitVersion" : "33934938e0e95d534cebbaff656cde916b9c3573"
},
"ok" : 1
}
As you can see executionStats.executionStages.inputStage.nReturned is 0 and executionStats.totalDocsExamined is so 0. It's ok, I guess there is no documents with login like entered. But if I want search users by email I'll do next:
rs0:PRIMARY> db.users.explain('executionStats').find({'emails.email' : /test123123123/})
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "mydb.users",
"indexFilterSet" : false,
"parsedQuery" : {
"emails.email" : /test123123123/
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"emails.email" : /test123123123/
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"emails.email" : 1
},
"indexName" : "emails.email_1",
"isMultiKey" : true,
"direction" : "forward",
"indexBounds" : {
"emails.email" : [
"[\"\", {})",
"[/test123123123/, /test123123123/]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 7666,
"totalKeysExamined" : 699016,
"totalDocsExamined" : 698993,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"emails.email" : /test123123123/
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 7355,
"works" : 699017,
"advanced" : 0,
"needTime" : 699016,
"needFetch" : 0,
"saveState" : 5462,
"restoreState" : 5462,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 698993,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 698993,
"executionTimeMillisEstimate" : 1630,
"works" : 699016,
"advanced" : 698993,
"needTime" : 23,
"needFetch" : 0,
"saveState" : 5462,
"restoreState" : 5462,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"emails.email" : 1
},
"indexName" : "emails.email_1",
"isMultiKey" : true,
"direction" : "forward",
"indexBounds" : {
"emails.email" : [
"[\"\", {})",
"[/test123123123/, /test123123123/]"
]
},
"keysExamined" : 699016,
"dupsTested" : 699016,
"dupsDropped" : 23,
"seenInvalidated" : 0,
"matchTested" : 0
}
}
},
"serverInfo" : {
"host" : "myhost",
"port" : 27017,
"version" : "3.0.12",
"gitVersion" : "33934938e0e95d534cebbaff656cde916b9c3573"
},
"ok" : 1
}
And here executionStats.executionStages.inputStage.nReturned (and executionStats.totalDocsExamined) is equal 698993 (executionStats.nReturned is 0 like in first query)
Question
Why when I use search with multikey index (users.user) on the ixscan stage returns all my collection and fetch stage occurs all collection. But If I use search by non-multikey index (login) ixscan stage scans expected values and on the fetch stage I give what I want.
UPD: when I use regular expression not like /smth/, but /^smth/ then scan by emails.email field returns also 0 elements. Why multikey and ordinary index give me different results for regular expression like /smth/ ?

Because it is multikey index.
explained here
When a query filter specifies an exact match for an array as a whole, MongoDB can use the multikey index to look up the first element of the query array but cannot use the multikey index scan to find the whole array. Instead, after using the multikey index to look up the first element of the query array, MongoDB retrieves the associated documents and filters for documents whose array matches the array in the query.

Related

mongodb contains query empty result slow

I have around 10 millions document in MongoDB.
I'm trying to search for text inside the db db.outMessage.find({ "text" : /.*m.*/}) but it took too long (around 30 second) with no result, but if I search for existing text it took less than a second.
I tried to put index on text with same result.
db.outMessage.find({ "text" : /.*m.*/}).explain(true)
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "notification_center.outMessage",
"indexFilterSet" : false,
"parsedQuery" : {
"text" : {
"$regex" : ".*m.*"
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"filter" : {
"text" : {
"$regex" : ".*m.*"
}
},
"keyPattern" : {
"text" : 1
},
"indexName" : "text",
"isMultiKey" : false,
"multiKeyPaths" : {
"text" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"text" : [
"[\"\", {})",
"[/.*m.*/, /.*m.*/]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 14354,
"totalKeysExamined" : 10263270,
"totalDocsExamined" : 0,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 0,
"executionTimeMillisEstimate" : 12957,
"works" : 10263271,
"advanced" : 0,
"needTime" : 10263270,
"needYield" : 0,
"saveState" : 80258,
"restoreState" : 80258,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 0,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"filter" : {
"text" : {
"$regex" : ".*m.*"
}
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 12461,
"works" : 10263271,
"advanced" : 0,
"needTime" : 10263270,
"needYield" : 0,
"saveState" : 80258,
"restoreState" : 80258,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"text" : 1
},
"indexName" : "text",
"isMultiKey" : false,
"multiKeyPaths" : {
"text" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"text" : [
"[\"\", {})",
"[/.*m.*/, /.*m.*/]"
]
},
"keysExamined" : 10263270,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
},
"allPlansExecution" : [ ]
},
"serverInfo" : {
"host" : "acsdptest.arabiacell.net",
"port" : 27017,
"version" : "3.4.7",
"gitVersion" : "cf38c1b8a0a8dca4a11737581beafef4fe120bcd"
},
The index will essentially be a list of all the values of the text field, in lexicographical order, i.e. sorted by the first letter.
Since the query executor has no way to predict which values might contain an 'm', it must examine all of the index entries.
In the case of this query, that means 10,263,270 index keys were examined, after being read from disk if the index was not already in the cache.
If this is actually a keyword search and not a single-letter match, instead of $regex, you might be able to make use of the $text query operator, which requires a text index

query text search index on compound text search and timestamp mongodb

I have a collection, with a total of documents about 65 million records like this
{
"_id" : ObjectId("5e0b814660da38d499ecf178"),
"brands" : null,
"client_id" : null,
"code_co_owner" : ",7359562, ",
"code_segment" : "7359562",
"core" : "",
"created" : "01-01-2020",
"created_full" : "01-01-2020 00:00:27",
"created_int" : NumberLong(1577811627),
"email" : ",phamthanhlam17_gmail_com, "
.....
}
I made an compound index on (email, created_int): {"email": text, created_int: -1} for search and filter which name in a range of created_int
But I see that it's poor performance on search.
I tried to use explain on query:
db.getCollection('profile_20201').explain().find({"$text":{"$search":"phamthanhlam17_gmail_com"},
"created_int":{"$lte":1585627013, "$gte":1583035013}}).count()
The explain result is:
{
"queryPlanner" : {
"plannerVersion" : 1,
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"created_int" : {
"$lte" : 1585627013.0
}
},
{
"created_int" : {
"$gte" : 1583035013.0
}
},
{
"$text" : {
"$search" : "phamthanhlam17_gmail_com",
"$language" : "english",
"$caseSensitive" : false,
"$diacriticSensitive" : false
}
}
]
},
"winningPlan" : {
"stage" : "COUNT",
"inputStage" : {
"stage" : "TEXT",
"indexPrefix" : {},
"indexName" : "email_text_created_int_-1",
"parsedTextQuery" : {
"terms" : [
"phamthanhlam17_gmail_com"
],
"negatedTerms" : [],
"phrases" : [],
"negatedPhrases" : []
},
"textIndexVersion" : 3,
"inputStage" : {
"stage" : "TEXT_MATCH",
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "OR",
"filter" : {
"$and" : [
{
"created_int" : {
"$lte" : 1585627013.0
}
},
{
"created_int" : {
"$gte" : 1583035013.0
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"_fts" : "text",
"_ftsx" : 1,
"created_int" : -1.0
},
"indexName" : "email_text_created_int_-1",
"isMultiKey" : true,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "backward",
"indexBounds" : {}
}
}
}
}
}
},
"rejectedPlans" : []
},
"serverInfo" : {
},
"ok" : 1.0
}
It's explain stats:
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "namespace",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"created_int" : {
"$lte" : 1585627013.0
}
},
{
"created_int" : {
"$gte" : 1583035013.0
}
},
{
"$text" : {
"$search" : "phamthanhlam17_gmail_com",
"$language" : "english",
"$caseSensitive" : false,
"$diacriticSensitive" : false
}
}
]
},
"winningPlan" : {
"stage" : "COUNT",
"inputStage" : {
"stage" : "TEXT",
"indexPrefix" : {},
"indexName" : "email_text_created_int_-1",
"parsedTextQuery" : {
"terms" : [
"phamthanhlam17_gmail_com"
],
"negatedTerms" : [],
"phrases" : [],
"negatedPhrases" : []
},
"textIndexVersion" : 3,
"inputStage" : {
"stage" : "TEXT_MATCH",
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "OR",
"filter" : {
"$and" : [
{
"created_int" : {
"$lte" : 1585627013.0
}
},
{
"created_int" : {
"$gte" : 1583035013.0
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"_fts" : "text",
"_ftsx" : 1,
"created_int" : -1.0
},
"indexName" : "email_text_created_int_-1",
"isMultiKey" : true,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "backward",
"indexBounds" : {}
}
}
}
}
}
},
"rejectedPlans" : []
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 1499057,
"totalKeysExamined" : 72544123,
"totalDocsExamined" : 39448083,
"executionStages" : {
"stage" : "COUNT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 1483861,
"works" : 72544124,
"advanced" : 0,
"needTime" : 72544123,
"needYield" : 0,
"saveState" : 578233,
"restoreState" : 578233,
"isEOF" : 1,
"invalidates" : 0,
"nCounted" : 39448083,
"nSkipped" : 0,
"inputStage" : {
"stage" : "TEXT",
"nReturned" : 39448083,
"executionTimeMillisEstimate" : 1475831,
"works" : 72544124,
"advanced" : 39448083,
"needTime" : 33096040,
"needYield" : 0,
"saveState" : 578233,
"restoreState" : 578233,
"isEOF" : 1,
"invalidates" : 0,
"indexPrefix" : {},
"indexName" : "email_text_created_int_-1",
"parsedTextQuery" : {
"terms" : [
"phamthanhlam17_gmail_com"
],
"negatedTerms" : [],
"phrases" : [],
"negatedPhrases" : []
},
"textIndexVersion" : 3,
"inputStage" : {
"stage" : "TEXT_MATCH",
"nReturned" : 39448083,
"executionTimeMillisEstimate" : 1473041,
"works" : 72544124,
"advanced" : 39448083,
"needTime" : 33096040,
"needYield" : 0,
"saveState" : 578233,
"restoreState" : 578233,
"isEOF" : 1,
"invalidates" : 0,
"docsRejected" : 0,
"inputStage" : {
"stage" : "FETCH",
"nReturned" : 39448083,
"executionTimeMillisEstimate" : 1465951,
"works" : 72544124,
"advanced" : 39448083,
"needTime" : 33096040,
"needYield" : 0,
"saveState" : 578233,
"restoreState" : 578233,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 39448083,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "OR",
"filter" : {
"$and" : [
{
"created_int" : {
"$lte" : 1585627013.0
}
},
{
"created_int" : {
"$gte" : 1583035013.0
}
}
]
},
"nReturned" : 39448083,
"executionTimeMillisEstimate" : 439664,
"works" : 72544124,
"advanced" : 39448083,
"needTime" : 33096040,
"needYield" : 0,
"saveState" : 578233,
"restoreState" : 578233,
"isEOF" : 1,
"invalidates" : 0,
"dupsTested" : 72544123,
"dupsDropped" : 0,
"recordIdsForgotten" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 72544123,
"executionTimeMillisEstimate" : 291188,
"works" : 72544124,
"advanced" : 72544123,
"needTime" : 0,
"needYield" : 0,
"saveState" : 578233,
"restoreState" : 578233,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"_fts" : "text",
"_ftsx" : 1,
"created_int" : -1.0
},
"indexName" : "email_text_created_int_-1",
"isMultiKey" : true,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "backward",
"indexBounds" : {},
"keysExamined" : 72544123,
"seeks" : 1,
"dupsTested" : 72544123,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
}
}
}
},
"serverInfo" : {
},
"ok" : 1.0
}```
So, is the index is cover the query?
Or which index will give me better performance for this problem?
Thank you.
Well, it seems like you have created the compound index with text. But in official MongoDB Documentation, it says that:
A compound index can include a text index key in combination with ascending/descending index keys. However, these compound indexes have the following restrictions:
A compound text index cannot include any other special index types, such as multi-key or geospatial index fields.
If the compound text index includes keys preceding the text index key, to perform a $text search, the query predicate must include equality match conditions on the preceding keys. (You are using the range query here)
When creating a compound text index, all text index keys must be listed adjacently in the index specification document.
So, that's the first issue.
Next, I want you to have a look at prefixes, it will help you understand how the compound indexes will be used in your query.
Hope this will help you understand the problem :)

MongoDB find query very slow even with index

I don't understand why the following query is so slow, the explain shows it will take 74+ seconds to finish, in spite of the presence of index.
both dev_id and _id are indexed I can assure you, it seems just not helpful at all.
db.DeviceLoginLog.find({"dev_id": "xxx"}).skip(0).limit(10).sort({"_id": -1}).explain("executionStats");
Can anyone help me to interpret explain output and advise me how to speed up?
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "example.DeviceLoginLog",
"indexFilterSet" : false,
"parsedQuery" : {
"dev_id" : {
"$eq" : "xxx"
}
},
"winningPlan" : {
"stage" : "SORT",
"sortPattern" : {
"_id" : -1
},
"limitAmount" : 10,
"inputStage" : {
"stage" : "KEEP_MUTATIONS",
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"dev_id" : 1
},
"indexName" : "dev_id_1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"dev_id" : [
"[\"xxx\", \"xxx\"]"
]
}
}
}
}
},
"rejectedPlans" : [
{
"stage" : "LIMIT",
"limitAmount" : 4,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"dev_id" : {
"$eq" : "xxx"
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"_id" : 1
},
"indexName" : "_id_",
"isMultiKey" : false,
"direction" : "backward",
"indexBounds" : {
"_id" : [
"[MaxKey, MinKey]"
]
}
}
}
}
]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 10,
"executionTimeMillis" : 74867,
"totalKeysExamined" : 9203,
"totalDocsExamined" : 9203,
"executionStages" : {
"stage" : "SORT",
"nReturned" : 10,
"executionTimeMillisEstimate" : 49860,
"works" : 9537,
"advanced" : 10,
"needTime" : 9204,
"needFetch" : 321,
"saveState" : 1864,
"restoreState" : 1864,
"isEOF" : 1,
"invalidates" : 1064,
"sortPattern" : {
"_id" : -1
},
"memUsage" : 1890,
"memLimit" : 33554432,
"limitAmount" : 10,
"inputStage" : {
"stage" : "KEEP_MUTATIONS",
"nReturned" : 9203,
"executionTimeMillisEstimate" : 49820,
"works" : 9525,
"advanced" : 9203,
"needTime" : 0,
"needFetch" : 321,
"saveState" : 1864,
"restoreState" : 1864,
"isEOF" : 1,
"invalidates" : 1064,
"inputStage" : {
"stage" : "FETCH",
"nReturned" : 9203,
"executionTimeMillisEstimate" : 49820,
"works" : 9525,
"advanced" : 9203,
"needTime" : 0,
"needFetch" : 321,
"saveState" : 1864,
"restoreState" : 1864,
"isEOF" : 1,
"invalidates" : 1064,
"docsExamined" : 9203,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 9203,
"executionTimeMillisEstimate" : 10,
"works" : 9204,
"advanced" : 9203,
"needTime" : 0,
"needFetch" : 0,
"saveState" : 1864,
"restoreState" : 1864,
"isEOF" : 1,
"invalidates" : 1064,
"keyPattern" : {
"dev_id" : 1
},
"indexName" : "dev_id_1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"dev_id" : [
"[\"xxx\", \"xxx\"]"
]
},
"keysExamined" : 9203,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0
}
}
}
}
},
"serverInfo" : {
"host" : "iZ231ear7c9Z",
"port" : 27017,
"version" : "3.0.3",
"gitVersion" : "b40106b36eecd1b4407eb1ad1af6bc60593c6105"
},
"ok" : 1
}
Thanks in advanceļ¼
The query used index {dev_id: 1} to find and then had to fetch matched docs into memory to sort without using an index. Create a compound index as {dev_id: 1, _id: -1} will improve performance.
See sort-and-non-prefix-subset-of-an-index.
"totalKeysExamined" : 9203,
"totalDocsExamined" : 9203,
That shows that the query had to examine each individual document. You aren't using an index on the _id field. Also depending on which fields you are returning, consider creating an index that allows for a covered query.
A covered query is a query that can be satisfied entirely using an
index and does not have to examine any documents. An index covers a
query when both of the following apply:
all the fields in the query are part of an index, and
all the fields returned in the results are in the same index.
https://docs.mongodb.com/manual/core/query-optimization/

Performance issue with $where clause in mongodb v3.0.7

I have collection with 104444219 records, when I perform full scan of collection it takes around 38038 milliseconds with the query
db.ORDER_MASTER.find()
But while performing query with $where clause
db.ORDER_DETALS.find({ "$where" : "this.GLB_ROOT_ORDER_ID == this.SYS_ORDER_ID"})
Also we have indexes on GLB_ROOT_ORDER_ID and SYS_ORDER_ID, on the same collection it takes 2064391 milliseconds while checking explain plan for both queries doing full scan, but why difference in execution time?
Is there any alternative for $where clause?
For
db.ORDER_MASTER.find({ "$where" : "obj.GLB_ROOT_ORDER_ID == obj.SYS_ORDER_ID"})
explain results
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "uat_test.ORDER_MASTER",
"indexFilterSet" : false,
"parsedQuery" : {
"$where" : "obj.GLB_ROOT_ORDER_ID == obj.SYS_ORDER_ID"
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"$where" : "obj.GLB_ROOT_ORDER_ID == obj.SYS_ORDER_ID"
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 93366348,
"executionTimeMillis" : 2064391,
"totalKeysExamined" : 0,
"totalDocsExamined" : 104444219,
"executionStages" : {
"stage" : "COLLSCAN",
"filter" : {
"$where" : "obj.GLB_ROOT_ORDER_ID == obj.SYS_ORDER_ID"
},
"nReturned" : 93366348,
"executionTimeMillisEstimate" : 2007680,
"works" : 104444221,
"advanced" : 93366348,
"needTime" : 11077872,
"needFetch" : 0,
"saveState" : 816961,
"restoreState" : 816961,
"isEOF" : 1,
"invalidates" : 0,
"direction" : "forward",
"docsExamined" : 104444219
}
},
"ok" : 1
}
For
db.ORDER_MASTER.find()
explain results
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "uat_test.ORDER_MASTER",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [ ]
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"$and" : [ ]
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 104444219,
"executionTimeMillis" : 38038,
"totalKeysExamined" : 0,
"totalDocsExamined" : 104444219,
"executionStages" : {
"stage" : "COLLSCAN",
"filter" : {
"$and" : [ ]
},
"nReturned" : 104444219,
"executionTimeMillisEstimate" : 26520,
"works" : 104444221,
"advanced" : 104444219,
"needTime" : 1,
"needFetch" : 0,
"saveState" : 815970,
"restoreState" : 815970,
"isEOF" : 1,
"invalidates" : 0,
"direction" : "forward",
"docsExamined" : 104444219
}
},
"ok" : 1
}

mongodb index find index sort

I would like to ask about mongodb indexes. Can I use a different index in the find and the sort. By example I have two indexes:
(a:-1)
(b:1,c:1)
What indexes uses this sentence?
({a:[$gt30}},{a:[$lt50}}]}.sort({c:1})
Can I use a different index in the find and the sort.
After reading some more into this you will see at the bottom of the documentation page on index intersectioning: http://docs.mongodb.org/manual/core/index-intersection/#index-intersection-and-sort
Index intersection does not apply when the sort() operation requires an index completely separate from the query predicate.
So no, even if ypou created an index of {c:1} it could not be used independantly to intersect {a:1}
What indexes uses this sentence?
In this case only {a:1} will be used.
Creating an index on a single field called Single Field Index.
Creating multiple Single Field indexes to boost your query and the sort performance won't help much!. You should use Compound Indexes instead.
Check the documentation on MongoDB: https://docs.mongodb.com/manual/core/index-compound/
If you want to learn how to index your fields and how to measure the performance of your queries.
And Check this tutorial on Youtube: https://dplink.app/nxLgvk7lR
Suppose I am having persons collection having documents like below :
{
dob:
{ age : 50} ,
gender : "male" ,
phone : ""
}
Now i create indexes as below .
1 : db.persons.createIndex({"dob.age" : -1})
2 : db.persons.createIndex({phone : 1 , gender : 1})
Now If i execute below query like yours
db.persons.explain("executionStats").find({$and : [ {"dob.age" : {$lt : 50} } ,
{"dob.age" : {$gt : 30} } ] } ).sort({gender : 1 })
I will get below execution stats :
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "college.persons",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"dob.age" : {
"$lt" : 50
}
},
{
"dob.age" : {
"$gt" : 30
}
}
]
},
"queryHash" : "22FEA299",
"planCacheKey" : "5E8F38C1",
"winningPlan" : {
"stage" : "SORT",
"sortPattern" : {
"phone" : 1
},
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"dob.age" : -1
},
"indexName" : "dob.age_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"dob.age" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"dob.age" : [
"(50.0, 30.0)"
]
}
}
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1734,
"executionTimeMillis" : 10,
"totalKeysExamined" : 1734,
"totalDocsExamined" : 1734,
"executionStages" : {
"stage" : "SORT",
"nReturned" : 1734,
"executionTimeMillisEstimate" : 0,
"works" : 3471,
"advanced" : 1734,
"needTime" : 1736,
"needYield" : 0,
"saveState" : 27,
"restoreState" : 27,
"isEOF" : 1,
"sortPattern" : {
"phone" : 1
},
"memUsage" : 1914799,
"memLimit" : 33554432,
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"nReturned" : 1734,
"executionTimeMillisEstimate" : 0,
"works" : 1736,
"advanced" : 1734,
"needTime" : 1,
"needYield" : 0,
"saveState" : 27,
"restoreState" : 27,
"isEOF" : 1,
"inputStage" : {
"stage" : "FETCH",
"nReturned" : 1734,
"executionTimeMillisEstimate" : 0,
"works" : 1735,
"advanced" : 1734,
"needTime" : 0,
"needYield" : 0,
"saveState" : 27,
"restoreState" : 27,
"isEOF" : 1,
"docsExamined" : 1734,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1734,
"executionTimeMillisEstimate" : 0,
"works" : 1735,
"advanced" : 1734,
"needTime" : 0,
"needYield" : 0,
"saveState" : 27,
"restoreState" : 27,
"isEOF" : 1,
"keyPattern" : {
"dob.age" : -1
},
"indexName" : "dob.age_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"dob.age" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"dob.age" : [
"(50.0, 30.0)"
]
},
"keysExamined" : 1734,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0
}
}
}
}
},
"serverInfo" : {
"host" : "RGGYSLT-0483",
"port" : 27017,
"version" : "4.2.0",
"gitVersion" : "a4b751dcf51dd249c5865812b390cfd1c0129c30"
},
"ok" : 1
}
This Means Data was fetched with IXScan on single field first and then sorted on
third field separately .
But the moment i change the query to sort on fields for which the index is already created things change . Now {"dob.age" : -1} index gets rejected .
In Mongo db Winning plan is the one for which 100 docs can be fetched early and Mongo db caches that plan for a query . Now this cache will be purged after 1000 docs insertions , index rebuild , server restarts or new index insertions.
Hence which index will be used depends upon winning plans .
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "college.persons",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"dob.age" : {
"$lt" : 50
}
},
{
"dob.age" : {
"$gt" : 30
}
}
]
},
"queryHash" : "DA8248FA",
"planCacheKey" : "E779554F",
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"dob.age" : {
"$lt" : 50
}
},
{
"dob.age" : {
"$gt" : 30
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"gender" : 1,
"phone" : 1
},
"indexName" : "gender_1_phone_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"gender" : [ ],
"phone" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"gender" : [
"[MinKey, MaxKey]"
],
"phone" : [
"[MinKey, MaxKey]"
]
}
}
},
"rejectedPlans" : [
{
"stage" : "SORT",
"sortPattern" : {
"gender" : 1,
"phone" : 1
},
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"dob.age" : -1
},
"indexName" : "dob.age_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"dob.age" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"dob.age" : [
"(50.0, 30.0)"
]
}
}
}
}
}
]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1734,
"executionTimeMillis" : 12,
"totalKeysExamined" : 5002,
"totalDocsExamined" : 5002,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"dob.age" : {
"$lt" : 50
}
},
{
"dob.age" : {
"$gt" : 30
}
}
]
},
"nReturned" : 1734,
"executionTimeMillisEstimate" : 0,
"works" : 5003,
"advanced" : 1734,
"needTime" : 3268,
"needYield" : 0,
"saveState" : 41,
"restoreState" : 41,
"isEOF" : 1,
"docsExamined" : 5002,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 5002,
"executionTimeMillisEstimate" : 0,
"works" : 5003,
"advanced" : 5002,
"needTime" : 0,
"needYield" : 0,
"saveState" : 41,
"restoreState" : 41,
"isEOF" : 1,
"keyPattern" : {
"gender" : 1,
"phone" : 1
},
"indexName" : "gender_1_phone_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"gender" : [ ],
"phone" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"gender" : [
"[MinKey, MaxKey]"
],
"phone" : [
"[MinKey, MaxKey]"
]
},
"keysExamined" : 5002,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0
}
}
},
"serverInfo" : {
"host" : "RGGYSLT-0483",
"port" : 27017,
"version" : "4.2.0",
"gitVersion" : "a4b751dcf51dd249c5865812b390cfd1c0129c30"
},
"ok" : 1
}