query wouldn't use suitable index - mongodb

I have a query
db.Product.find({
CategoryPath: /^399-305-352(-\d+)*$/,
"Availability.Status": {
$lt: 4
},
$or: [{
_id: {
$lt: 331000000
}
}, {
_id: {
$gt: 852000000,
$lt: 853000000
}
}, {
_id: {
$gt: 972000000,
$lt: 973000000
}
}]
}).sort({
"Availability.Status": 1,
Popularity: -1
});
with explain I find it uses index Availability.Status_1_Popularity_-1:
{
"cursor" : "BtreeCursor Availability.Status_1_Popularity_-1",
"isMultiKey" : false,
"n" : 913,
"nscannedObjects" : 470239,
"nscanned" : 470239,
"nscannedObjectsAllPlans" : 1387264,
"nscannedAllPlans" : 1387264,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 10838,
"nChunkSkips" : 0,
"millis" : 10117,
"indexBounds" : {
"Availability.Status" : [
[
-Infinity,
4
]
],
"Popularity" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
},
"server" : "dal05mgo13.sl.dx:27017",
"filterSet" : false
}
this is pretty slow for me. I actually have another index CategoryPath_1_Availability.Status_1 which I think is a better choice. but when I force mongodb to use it with hint, I get an error:
{
"$err" : "Runner error: Overflow sort stage buffered data usage of 33581891 bytes exceeds internal limit of 33554432 bytes",
"code" : 17144
}
Now what I don't understand is, with the conditions specified in find, there are only 913 results selected, even without index, sort shouldn't have used up 32MB memory to sort the 913 records. Can anyone tell me what's happening?
I'm using MongoDB 2.6.10 x86_64
EDIT: my colleague just created a new index Availability.Status_1_Popularity_-1_CategoryPath_1 which is now winning from other plans. I still don't understand why though. Here are the detail explain info:
{
"cursor" : "BtreeCursor Availability.Status_1_Popularity_-1_CategoryPath_1",
"isMultiKey" : true,
"n" : 913,
"nscannedObjects" : 1325,
"nscanned" : 1930,
"nscannedObjectsAllPlans" : 7729,
"nscannedAllPlans" : 8334,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 64,
"nChunkSkips" : 0,
"millis" : 45,
"indexBounds" : {
"Availability.Status" : [
[
-Infinity,
4
]
],
"Popularity" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
],
"CategoryPath" : [
[
"399-305-352",
"399-305-353"
],
[
/^399-305-352(-\d+)*$/,
/^399-305-352(-\d+)*$/
]
]
},
"allPlans" : [
{
"cursor" : "BtreeCursor Availability.Status_1_Popularity_-1_CategoryPath_1",
"isMultiKey" : true,
"n" : 913,
"nscannedObjects" : 1325,
"nscanned" : 1930,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"Availability.Status" : [
[
-Infinity,
4
]
],
"Popularity" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
],
"CategoryPath" : [
[
"399-305-352",
"399-305-353"
],
[
/^399-305-352(-\d+)*$/,
/^399-305-352(-\d+)*$/
]
]
}
},
{
"cursor" : "BtreeCursor Availability.Status_1_Popularity_-1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 306,
"nscanned" : 306,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"Availability.Status" : [
[
-Infinity,
4
]
],
"Popularity" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
},
{
"clauses" : [
{
"cursor" : "BtreeCursor _id_",
"isMultiKey" : false,
"n" : 305,
"nscannedObjects" : 305,
"nscanned" : 305,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
852000000,
853000000
]
]
}
},
{
"cursor" : "BtreeCursor _id_",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
972000000,
973000000
]
]
}
},
{
"cursor" : "BtreeCursor _id_",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
-Infinity,
331000000
]
]
}
}
],
"cursor" : "QueryOptimizerCursor",
"n" : 0,
"nscannedObjects" : 305,
"nscanned" : 305,
"scanAndOrder" : true,
"nChunkSkips" : 0
},
{
"clauses" : [
{
"cursor" : "BtreeCursor _id_",
"isMultiKey" : false,
"n" : 7,
"nscannedObjects" : 7,
"nscanned" : 7,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
972000000,
973000000
]
]
}
},
{
"cursor" : "BtreeCursor _id_1_Availability.Status_1_Popularity_-1",
"isMultiKey" : false,
"n" : 297,
"nscannedObjects" : 297,
"nscanned" : 297,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
852000000,
853000000
]
],
"Availability.Status" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"Popularity" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
},
{
"cursor" : "BtreeCursor _id_",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
-Infinity,
331000000
]
]
}
}
],
"cursor" : "QueryOptimizerCursor",
"n" : 0,
"nscannedObjects" : 304,
"nscanned" : 304,
"scanAndOrder" : true,
"nChunkSkips" : 0
},
{
"clauses" : [
{
"cursor" : "BtreeCursor _id_",
"isMultiKey" : false,
"n" : 305,
"nscannedObjects" : 305,
"nscanned" : 305,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
852000000,
853000000
]
]
}
},
{
"cursor" : "BtreeCursor _id_1_Availability.Status_1_Popularity_-1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
972000000,
973000000
]
],
"Availability.Status" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"Popularity" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
},
{
"cursor" : "BtreeCursor _id_",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
-Infinity,
331000000
]
]
}
}
],
"cursor" : "QueryOptimizerCursor",
"n" : 0,
"nscannedObjects" : 305,
"nscanned" : 305,
"scanAndOrder" : true,
"nChunkSkips" : 0
},
{
"clauses" : [
{
"cursor" : "BtreeCursor _id_1_Availability.Status_1_Popularity_-1",
"isMultiKey" : false,
"n" : 305,
"nscannedObjects" : 305,
"nscanned" : 305,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
852000000,
853000000
]
],
"Availability.Status" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"Popularity" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
},
{
"cursor" : "BtreeCursor _id_1_Availability.Status_1_Popularity_-1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
972000000,
973000000
]
],
"Availability.Status" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"Popularity" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
},
{
"cursor" : "BtreeCursor _id_",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
-Infinity,
331000000
]
]
}
}
],
"cursor" : "QueryOptimizerCursor",
"n" : 0,
"nscannedObjects" : 305,
"nscanned" : 305,
"scanAndOrder" : true,
"nChunkSkips" : 0
},
{
"clauses" : [
{
"cursor" : "BtreeCursor _id_",
"isMultiKey" : false,
"n" : 305,
"nscannedObjects" : 305,
"nscanned" : 305,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
852000000,
853000000
]
]
}
},
{
"cursor" : "BtreeCursor _id_",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
972000000,
973000000
]
]
}
},
{
"cursor" : "BtreeCursor _id_1_Availability.Status_1_Popularity_-1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"_id" : [
[
-Infinity,
331000000
]
],
"Availability.Status" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"Popularity" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
}
],
"cursor" : "QueryOptimizerCursor",
"n" : 0,
"nscannedObjects" : 305,
"nscanned" : 305,
"scanAndOrder" : true,
"nChunkSkips" : 0
}
],
"server" : "dal05mgo12.sl.dx:27017",
"filterSet" : false,
"stats" : {
"type" : "FETCH",
"works" : 1931,
"yields" : 64,
"unyields" : 64,
"invalidates" : 0,
"advanced" : 913,
"needTime" : 1017,
"needFetch" : 0,
"isEOF" : 1,
"alreadyHasObj" : 0,
"forcedFetches" : 0,
"matchTested" : 913,
"children" : [
{
"type" : "IXSCAN",
"works" : 1931,
"yields" : 64,
"unyields" : 64,
"invalidates" : 0,
"advanced" : 1325,
"needTime" : 605,
"needFetch" : 0,
"isEOF" : 1,
"keyPattern" : "{ Availability.Status: 1.0, Popularity: -1.0, CategoryPath: 1.0 }",
"isMultiKey" : 1,
"boundsVerbose" : "field #0['Availability.Status']: [-inf.0, 4.0), field #1['Popularity']: [MaxKey, MinKey], field #2['CategoryPath']: [\"399-305-352\", \"399-305-353\"), [/^399-305-352(-\\d+)*$/, /^399-305-352(-\\d+)*$/]",
"yieldMovedCursor" : 0,
"dupsTested" : 1325,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0,
"keysExamined" : 1930,
"children" : [ ]
}
]
}
}

That's because the order of the fields in the index matters.
CategoryPath_1_Availability.Status_1 translates for the following indexing order: index by CategoryPath then by Availability.Status.
But you want the index to start with Availability.Status, and mongo checks to see if there is any index that starts with Availability.Status (ascending), and there isn't (before your friend created the new index). Order matters :)
As a general rule: lets say you have the following fields in a collection: a, b and c. Let's set an index on a and b (a ascending, b ascending). You will be able to use this index in a sort only if the sort starts with a (ascending), or a (ascending) and b (ascending). Hope you understand :)

Related

Mongodb log show they're using IXScan but db.currentOp() no

On mongodb log shows they're using IXScan
[conn37225] command hone.$cmd command: count { count: "events", query:
{ eventName: "Started", createdAt: { $gt: new Date(1449789260690),
$lte: new Date(1450221260693) }, data.quizId:
"54fe05f26aa23aeb72e3fdbb" }, fields: null } planSummary: IXSCAN {
createdAt: 1, data.quizId: 1, eventName: 1 } keyUpdates:0
numYields:4279 locks(micros) r:53800992 reslen:48 38679ms
but on db.currentOp() don't
{
"opid" : 4719819,
"active" : true,
"secs_running" : 4,
"microsecs_running" : NumberLong(4221829),
"op" : "query",
"ns" : "hone.events",
"query" : {
"count" : "events",
"query" : {
"eventName" : "Started",
"createdAt" : {
"$gt" : ISODate("2015-12-10T23:14:20.690Z"),
"$lte" : ISODate("2015-12-15T23:14:20.693Z")
},
"data.quizId" : "54fe05f26aa23aeb72e3fdbb"
},
"fields" : null
},
"client" : "10.8.0.7:43823",
"desc" : "conn37225",
"threadId" : "0x7f60aee9a700",
"connectionId" : 37225,
"locks" : {
"^" : "r",
"^hone" : "R"
},
"waitingForLock" : false,
"numYields" : 384,
"lockStats" : {
"timeLockedMicros" : {
"r" : NumberLong(6417513),
"w" : NumberLong(0)
},
"timeAcquiringMicros" : {
"r" : NumberLong(800491),
"w" : NumberLong(0)
}
}
}
Is the mongodb using properly the { createdAt: 1, data.quizId: 1, eventName: 1 } index?
using hint() with explain() is possible see the difference.
with hint() use specifically that index and works fast.
I'm wondering know what is causing it to be slower.
Without hint
> db.events.find({ eventName: "Completed", createdAt: { $gt: new Date(1449945185127), $lte: new Date(1450377185140) }, "data.quizId": "55ce6dde5239249a70f9ef54" }).explain("executionStats")
{
"cursor" : "BtreeCursor createdAt_1_data.quizId_1_eventName_1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 2519326,
"nscannedObjectsAllPlans" : 2543445,
"nscannedAllPlans" : 7536363,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 79008,
"nChunkSkips" : 0,
"millis" : 74443,
"indexBounds" : {
"createdAt" : [
[
ISODate("2015-12-12T18:33:05.127Z"),
ISODate("2015-12-17T18:33:05.140Z")
]
],
"data.quizId" : [
[
"55ce6dde5239249a70f9ef54",
"55ce6dde5239249a70f9ef54"
]
],
"eventName" : [
[
"Completed",
"Completed"
]
]
},
"allPlans" : [
{
"cursor" : "BtreeCursor createdAt_1_data.quizId_1_eventName_1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 2519326,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"createdAt" : [
[
ISODate("2015-12-12T18:33:05.127Z"),
ISODate("2015-12-17T18:33:05.140Z")
]
],
"data.quizId" : [
[
"55ce6dde5239249a70f9ef54",
"55ce6dde5239249a70f9ef54"
]
],
"eventName" : [
[
"Completed",
"Completed"
]
]
}
},
{
"cursor" : "BtreeCursor eventName_1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 2497710,
"nscanned" : 2497710,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"eventName" : [
[
"Completed",
"Completed"
]
]
}
},
{
"cursor" : "BtreeCursor createdAt_1_data.questionId_1_eventName_1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 45735,
"nscanned" : 2519327,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"createdAt" : [
[
ISODate("2015-12-12T18:33:05.127Z"),
ISODate("2015-12-17T18:33:05.140Z")
]
],
"data.questionId" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"eventName" : [
[
"Completed",
"Completed"
]
]
}
}
],
"server" : "mongodb-05:27017",
"filterSet" : false,
"stats" : {
"type" : "FETCH",
"works" : 2519328,
"yields" : 79008,
"unyields" : 79008,
"invalidates" : 0,
"advanced" : 0,
"needTime" : 2519326,
"needFetch" : 0,
"isEOF" : 1,
"alreadyHasObj" : 0,
"forcedFetches" : 0,
"matchTested" : 0,
"children" : [
{
"type" : "IXSCAN",
"works" : 2519327,
"yields" : 79008,
"unyields" : 79008,
"invalidates" : 0,
"advanced" : 0,
"needTime" : 2519326,
"needFetch" : 0,
"isEOF" : 1,
"keyPattern" : "{ createdAt: 1, data.quizId: 1, eventName: 1 }",
"isMultiKey" : 0,
"boundsVerbose" : "field #0['createdAt']: (new Date(1449945185127), new Date(1450377185140)], field #1['data.quizId']: [\"55ce6dde5239249a70f9ef54\", \"55ce6dde5239249a70f9ef54\"], field #2['eventName']: [\"Completed\", \"Completed\"]",
"yieldMovedCursor" : 0,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0,
"keysExamined" : 2519326,
"children" : [ ]
}
]
}
}
With hint
> db.events.find({ eventName: "Completed", createdAt: { $gt: new Date(1449945185127), $lte: new Date(1450377185140) }, "data.quizId": "55ce6dde5239249a70f9ef54" }).hint('createdAt_1_data.quizId_1_eventName_1').explain("executionStats")
{
"cursor" : "BtreeCursor createdAt_1_data.quizId_1_eventName_1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 2519326,
"nscannedObjectsAllPlans" : 0,
"nscannedAllPlans" : 2519326,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 19682,
"nChunkSkips" : 0,
"millis" : 8211,
"indexBounds" : {
"createdAt" : [
[
ISODate("2015-12-12T18:33:05.127Z"),
ISODate("2015-12-17T18:33:05.140Z")
]
],
"data.quizId" : [
[
"55ce6dde5239249a70f9ef54",
"55ce6dde5239249a70f9ef54"
]
],
"eventName" : [
[
"Completed",
"Completed"
]
]
},
"allPlans" : [
{
"cursor" : "BtreeCursor createdAt_1_data.quizId_1_eventName_1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 2519326,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"createdAt" : [
[
ISODate("2015-12-12T18:33:05.127Z"),
ISODate("2015-12-17T18:33:05.140Z")
]
],
"data.quizId" : [
[
"55ce6dde5239249a70f9ef54",
"55ce6dde5239249a70f9ef54"
]
],
"eventName" : [
[
"Completed",
"Completed"
]
]
}
}
],
"server" : "mongodb-05:27017",
"filterSet" : false,
"stats" : {
"type" : "FETCH",
"works" : 2519327,
"yields" : 19682,
"unyields" : 19682,
"invalidates" : 0,
"advanced" : 0,
"needTime" : 2519326,
"needFetch" : 0,
"isEOF" : 1,
"alreadyHasObj" : 0,
"forcedFetches" : 0,
"matchTested" : 0,
"children" : [
{
"type" : "IXSCAN",
"works" : 2519327,
"yields" : 19682,
"unyields" : 19682,
"invalidates" : 0,
"advanced" : 0,
"needTime" : 2519326,
"needFetch" : 0,
"isEOF" : 1,
"keyPattern" : "{ createdAt: 1, data.quizId: 1, eventName: 1 }",
"isMultiKey" : 0,
"boundsVerbose" : "field #0['createdAt']: (new Date(1449945185127), new Date(1450377185140)], field #1['data.quizId']: [\"55ce6dde5239249a70f9ef54\", \"55ce6dde5239249a70f9ef54\"], field #2['eventName']: [\"Completed\", \"Completed\"]",
"yieldMovedCursor" : 0,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0,
"keysExamined" : 2519326,
"children" : [ ]
}
]
}
}

Mongo selecting the wrong index

I'm using mongo db 2.6.9.
I created 2 indexes on a collection and i don`t understand the reson that the query planer allways selects the wrong index.
I would like to understand what I'm missing.
First Index:
{
"TimeStamp":1,
"A":1,
"B":1,
}
Second Index:
{
"TimeStamp":1,
"A":1,
"C":1,
}
When I'm useing the following query the planner selects the first index:
db.collection.find({"TimeStamp":{ "$gte" : ISODate("2015-04-14T00:00:00Z"), "$lt" : ISODate("2015-04-15T00:00:00Z") },"C":2137,"A":1}).explain()
explain({verbose:1}) results:
{
"cursor" : "BtreeCursor IX_First",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"nscannedObjectsAllPlans" : 0,
"nscannedAllPlans" : 0,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"TimeStamp" : [
[
ISODate("2015-04-14T00:00:00Z"),
ISODate("2015-04-15T00:00:00Z")
]
],
"A" : [
[
1,
1
]
],
"B" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
},
"allPlans" : [
{
"cursor" : "BtreeCursor IX_First",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"TimeStamp" : [
[
ISODate("2015-04-14T00:00:00Z"),
ISODate("2015-04-15T00:00:00Z")
]
],
"A" : [
[
1,
1
]
],
"B" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
},
{
"cursor" : "BtreeCursor IIX_Second",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"TimeStamp" : [
[
ISODate("2015-04-14T00:00:00Z"),
ISODate("2015-04-15T00:00:00Z")
]
],
"A" : [
[
1,
1
]
],
"C" : [
[
2137,
2137
]
]
}
}
],
"server" : "mongo2:27017",
"filterSet" : false,
"stats" : {
"type" : "KEEP_MUTATIONS",
"works" : 2,
"yields" : 0,
"unyields" : 0,
"invalidates" : 0,
"advanced" : 0,
"needTime" : 0,
"needFetch" : 0,
"isEOF" : 1,
"children" : [
{
"type" : "FETCH",
"works" : 1,
"yields" : 0,
"unyields" : 0,
"invalidates" : 0,
"advanced" : 0,
"needTime" : 0,
"needFetch" : 0,
"isEOF" : 1,
"alreadyHasObj" : 0,
"forcedFetches" : 0,
"matchTested" : 0,
"children" : [
{
"type" : "IXSCAN",
"works" : 1,
"yields" : 0,
"unyields" : 0,
"invalidates" : 0,
"advanced" : 0,
"needTime" : 0,
"needFetch" : 0,
"isEOF" : 1,
"keyPattern" : "{ TimeStamp: 1, A: 1, B: 1}",
"isMultiKey" : 0,
"boundsVerbose" : "field #0['TimeStamp']: [new Date(1428969600000), new Date(1429056000000)), field #1['A']: [1.0, 1.0], field #2['B']: [MinKey, MaxKey]",
"yieldMovedCursor" : 0,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0,
"keysExamined" : 0,
"children" : [ ]
}
]
}
]
}
}
That's because the order of the index fields matters in this case. Try swapping A and C:
db.collection.find({"TimeStamp":{ "$gte" : ISODate("2015-04-14T00:00:00Z"), "$lt" : ISODate("2015-04-15T00:00:00Z") },"A":1,"C":2137}).explain()

Mongodb Compound index and sorting

I have this collection :
db.place.find() :
{
_id : "p1",
alterNames : ["abcd","abcD"],
population : 122
}
{
_id : "p2",
alterNames : ["qsdf","qsDF"],
population : 100
}
I want to find documents having alterNames starting with "ab" and sort them by population.
I created this index : {alterNames : 1, population : -1}
My query :
db.place.find({alterNames : /^ab/}).sort({population : -1}).limit(10).explain()
I was waiting to see "n" = "nScannedObjects" = 10
What I got :
"n" = 10
"nScannedObjects" = 4765
Did I miss a thing?
Edit :
Here is the full explain :
db.place.find({alterNames : /^pari/ }).sort({population : -1}).limit(10).explain()
"clauses" : [
{
"cursor" : "BtreeCursor alterNames_1_population_-1",
"isMultiKey" : true,
"n" : 10,
"nscannedObjects" : 4765,
"nscanned" : 4883,
"scanAndOrder" : true,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"alterNames" : [
[
"pari",
"parj"
],
[
/^pari/,
/^pari/
]
],
"population" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
},
{
"cursor" : "BtreeCursor ",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : true,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"alterNames" : [
[
"pari",
"parj"
],
[
/^pari/,
/^pari/
]
],
"population" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
}
],
"cursor" : "QueryOptimizerCursor",
"n" : 10,
"nscannedObjects" : 4765,
"nscanned" : 4883,
"nscannedObjectsAllPlans" : 4765,
"nscannedAllPlans" : 4883,
"scanAndOrder" : false,
"nYields" : 890,
"nChunkSkips" : 0,
"millis" : 396,
"server" : "localhost:27017",
"filterSet" : false
Your notation is confusing. I'm assuming your collection consists of documents that look like the two documents in the places array.
> db.test.find()
{ "_id" : "p1", "alterNames" : [ "abcd", "abcD" ], "population" : 122 }
{ "_id" : "p2", "alterNames" : [ "qsdf", "qsDF" ], "population" : 100 }
For a left-anchored regex like /^ab/, MongoDB converts the query to one that's actually a range query and can efficiently use the index
{ "alterNames" : /^ab/ } => { "alterNames" : { "$gte" : "ab", "$lt" : "ac" } }
Each value that matches the range, for example "abcd", has an index of population values below it for documents with an alterNames (multikey) value of "abcd". To return the matching documents in population-order, MongoDB has to externally sort the documents returned from each matching bucket. I believe that's the source of your higher nscannedObjects. If you check the explain (which would have been nice to include in its entirety), you should find scanAndOrder : true.

MongoDB index intersection

Hey I want to evaluate the performance of index intersection but I'm not able to get an intersection between two indices.
I've inserted some dummy records into my DB along this manual.
http://docs.mongodb.org/manual/core/index-intersection/
Insert code:
for(var i=0;i<1000;i++){
for(var j=0;j<100;j++){
db.t.insert({item:"abc"+i,qty:j})
}
}
Indices:
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "db.t"
},
{
"v" : 1,
"key" : {
"qty" : 1
},
"name" : "qty_1",
"ns" : "db.t"
},
{
"v" : 1,
"key" : {
"item" : 1
},
"name" : "item_1",
"ns" : "db.t"
}
]
Query:
db.t.find({item:"abc123",qty:{$gt:15}}).explain()
Result of explain:
{
"cursor" : "BtreeCursor item_1",
"isMultiKey" : false,
"n" : 84,
"nscannedObjects" : 100,
"nscanned" : 100,
"nscannedObjectsAllPlans" : 201,
"nscannedAllPlans" : 305,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 2,
"nChunkSkips" : 0,
"millis" : 1,
"indexBounds" : {
"item" : [
[
"abc123",
"abc123"
]
]
},
"server" : "brews18:27017",
"filterSet" : false
}
My question is why mongo is only using item as an index an does not use an intersection.
Thanks in advance
Well it actually does even though it does not in this case. To really see what is happening you need to look at the "verbose" form of explain, by adding true:
db.t.find({item:"abc123",qty:{$gt:15}}).explain(true)
{
"cursor" : "BtreeCursor item_1",
"isMultiKey" : false,
"n" : 84,
"nscannedObjects" : 100,
"nscanned" : 100,
"nscannedObjectsAllPlans" : 201,
"nscannedAllPlans" : 304,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 2,
"nChunkSkips" : 0,
"millis" : 2,
"indexBounds" : {
"item" : [
[
"abc123",
"abc123"
]
]
},
"allPlans" : [
{
"cursor" : "BtreeCursor item_1",
"isMultiKey" : false,
"n" : 84,
"nscannedObjects" : 100,
"nscanned" : 100,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"item" : [
[
"abc123",
"abc123"
]
]
}
},
{
"cursor" : "BtreeCursor qty_1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 101,
"nscanned" : 102,
"scanAndOrder" : false,
"indexOnly" : false,
"nChunkSkips" : 0,
"indexBounds" : {
"qty" : [
[
15,
Infinity
]
]
}
},
{
"cursor" : "Complex Plan",
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 102,
"nChunkSkips" : 0
}
],
Cut short, but the last part is what you are looking for. As explained in the manual, the appearance of "Complex Plan" means an intersection is being used.
{
"cursor" : "Complex Plan",
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 102,
"nChunkSkips" : 0
}
The only case here is that while it is being "looked at" it is not being chosen by the optimizer in this case as the most "optimal" query. So the optimizer is saying that in fact the plan using just the one selected index, is the one that will complete in the most responsive fashion.
So while the "intersection" was considered, it was not the "best fit" and the single index was chosen.

MongoDB index use on find all without hint

I've got a question on how to write an index properly to avoid resorting to a hint.
Sample "Test" Collection Schema
{
_id: ObjectId(<whatever>),
a: <whatever>,
b: <whatever>,
c: <whatever>,
d: <whatever>,
e: {
f: <whatever>,
g: <whatever>
}
}
Index on "Test"
db.test.ensureIndex( { "a": NumberInt(1), "c": NumberInt(1), "_id": NumberInt(1), "d": NumberInt(1) },
{ name: "a_1_c_1__id_1_d_1", background: true } );
Query without hint and query with hint...
> db.test.find({},{d:1}).explain();
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 752,
"nscannedObjects" : 752,
"nscanned" : 752,
"nscannedObjectsAllPlans" : 752,
"nscannedAllPlans" : 752,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 4,
"nChunkSkips" : 0,
"millis" : 5,
"indexBounds" : {
},
"server" : <whatever>
}
> db.test.find({},{d:1}).hint("a_1_c_1__id_1_d_1").explain();
{
"cursor" : "BtreeCursor a_1_c_1__id_1_d_1",
"isMultiKey" : false,
"n" : 752,
"nscannedObjects" : 752,
"nscanned" : 752,
"nscannedObjectsAllPlans" : 752,
"nscannedAllPlans" : 752,
"scanAndOrder" : false,
"indexOnly" : true,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"a" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"c" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"_id" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"d" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"server" : <whatever>
}
I'd (obviously) like the query to use the covered index but I don't know how to get there without using the hint. Is it possible? I'd prefer to manipulate the index vs. changing the query but changing the query is an option, if need be.
Turns out this is a known issue. Apologies for the post.
https://jira.mongodb.org/browse/SERVER-2109