Problemet är att inget av dina index faktiskt hjälper med den sorterade frågan. Detta är anledningen till det höga antalet skannade objekt och förekomsten av SORT_KEY_GENERATOR
steg (sortering i minnet, begränsat till 32 MB).
Den icke-sorterade frågan, å andra sidan, kan använda antingen { category: 1, _id: 1 }
eller { category: 1, _id: 1, sticky: 1, lastPostAt: 1 }
index. Observera att det är helt giltigt att använda båda, eftersom den ena innehåller prefixet av den andra. Se Prefix för mer information.
MongoDB find()
frågor använder vanligtvis bara ett index, så ett enda sammansatt index bör tillgodose alla parametrar i din fråga. Detta skulle inkludera båda parametrarna för find()
och sort()
.
En bra beskrivning av hur ditt index ska skapas finns i Optimizing MongoDB Compound Indexes. Låt oss ta artikelns huvudpoäng, där den sammansatta indexordningen ska vara equality --> sort --> range :
Din fråga "shape" är:
db.collection.find({category:..., _id: {$gt:...}})
.sort({sticky:-1, lastPostAt:-1, _id:1})
.limit(25)
Vi ser att:
category:...
är jämställdhetsticky:-1, lastPostAt:-1, _id:1
är sortera_id: {$gt:...}
är intervall
Så det sammansatta indexet du behöver är:
{category:1, sticky:-1, lastPostAt:-1, _id:1}
Där den vinnande planen för explain()
output av din fråga med ovanstående index visar:
"winningPlan": {
"stage": "LIMIT",
"limitAmount": 25,
"inputStage": {
"stage": "FETCH",
"inputStage": {
"stage": "IXSCAN",
"keyPattern": {
"category": 1,
"sticky": -1,
"lastPostAt": -1,
"_id": 1
},
"indexName": "category_1_sticky_-1_lastPostAt_-1__id_1",
"isMultiKey": false,
"multiKeyPaths": {
"category": [ ],
"sticky": [ ],
"lastPostAt": [ ],
"_id": [ ]
},
"isUnique": false,
"isSparse": false,
"isPartial": false,
"indexVersion": 2,
"direction": "forward",
"indexBounds": {
"category": [
"[ObjectId('5a779b31f4fa724121265142'), ObjectId('5a779b31f4fa724121265142')]"
],
"sticky": [
"[MaxKey, MinKey]"
],
"lastPostAt": [
"[MaxKey, MinKey]"
],
"_id": [
"(ObjectId('5a779b5cf4fa724121269be8'), ObjectId('ffffffffffffffffffffffff')]"
]
}
}
}
}
Observera att den vinnande planen inte innehåller en SORT_KEY_GENERATOR
skede. Detta innebär att indexet kan användas fullt ut för att svara på den sorterade frågan.