Problemet er, at ingen af dine indekser faktisk hjælper med den sorterede forespørgsel. Dette er årsagen til det høje antal scannede objekter og tilstedeværelsen af SORT_KEY_GENERATOR
fase (sortering i hukommelsen, begrænset til 32 MB).
Den ikke-sorterede forespørgsel kan på den anden side bruge enten { category: 1, _id: 1 }
eller { category: 1, _id: 1, sticky: 1, lastPostAt: 1 }
indekser. Bemærk, at det er helt gyldigt at bruge begge, da den ene indeholder præfikset af den anden. Se Præfikser for flere detaljer.
MongoDB find()
forespørgsler bruger typisk kun ét indeks, så et enkelt sammensat indeks bør tage højde for alle parametrene i din forespørgsel. Dette vil inkludere begge parametre for find()
og sort()
.
En god beskrivelse af, hvordan dit indeks skal oprettes, er tilgængelig i Optimering af MongoDB Compound Indexes. Lad os tage artiklens hovedpointe, hvor den sammensatte indeksrækkefølge skal være equality --> sort --> range :
Din forespørgsel "shape" er:
db.collection.find({category:..., _id: {$gt:...}})
.sort({sticky:-1, lastPostAt:-1, _id:1})
.limit(25)
Vi ser, at:
category:...
er lighedsticky:-1, lastPostAt:-1, _id:1
er sortér_id: {$gt:...}
er interval
Så det sammensatte indeks, du har brug for, er:
{category:1, sticky:-1, lastPostAt:-1, _id:1}
Hvor vinderplanen for explain()
output af din forespørgsel med ovenstående indeks viser:
"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')]"
]
}
}
}
}
Bemærk, at den vindende plan ikke indeholder en SORT_KEY_GENERATOR
scene. Det betyder, at indekset kan udnyttes fuldt ud til at svare på den sorterede forespørgsel.