Problem polega na tym, że żaden z Twoich indeksów nie pomaga w posortowanym zapytaniu. To jest powód dużej liczby skanowanych obiektów i obecności SORT_KEY_GENERATOR
etap (sortowanie w pamięci, ograniczone do 32 MB).
Z drugiej strony zapytanie nieposortowane może używać { category: 1, _id: 1 }
lub { category: 1, _id: 1, sticky: 1, lastPostAt: 1 }
indeksy. Pamiętaj, że użycie jednego z nich jest całkowicie poprawne, ponieważ jeden zawiera przedrostek z drugiej. Zobacz Prefiksy, aby uzyskać więcej informacji.
MongoDB find()
Zapytania zazwyczaj używają tylko jednego indeksu, więc jeden indeks złożony powinien obsługiwać wszystkie parametry zapytania. Obejmuje to oba parametry find()
i sort()
.
Dobry opis tego, jak powinien być tworzony Twój indeks, jest dostępny w Optymalizacji indeksów złożonych MongoDB. Przyjrzyjmy się głównemu punktowi artykułu, w którym uporządkowanie indeksów złożonych powinno być następujące:równość --> sortowanie --> zakres :
Twoje zapytanie „kształt” to:
db.collection.find({category:..., _id: {$gt:...}})
.sort({sticky:-1, lastPostAt:-1, _id:1})
.limit(25)
Widzimy, że:
category:...
to równośćsticky:-1, lastPostAt:-1, _id:1
to sortuj_id: {$gt:...}
to zakres
Tak więc potrzebny indeks złożony to:
{category:1, sticky:-1, lastPostAt:-1, _id:1}
Gdzie zwycięski plan explain()
wynik zapytania z powyższym indeksem pokazuje:
"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')]"
]
}
}
}
}
Pamiętaj, że zwycięski plan nie zawiera SORT_KEY_GENERATOR
scena. Oznacza to, że indeks może być w pełni wykorzystany do odpowiedzi na posortowane zapytanie.