De index zou het hele deel van de zoekopdracht moeten dekken (gelijkheidsgedeelte, sorteergedeelte en bereikgedeelte). Dit komt omdat in een typische find()
query, MongoDB gebruikt slechts één index. Het gebruikt bijvoorbeeld over het algemeen niet één index voor het gelijkheidsgedeelte en een andere index voor het sorteergedeelte.
Over het algemeen moet de volgorde van velden in de index het patroon van gelijkheid -> sorteren -> bereik volgen .
Dit wordt in detail beschreven in MongoDB samengestelde indexen optimaliseren .
Voor uw zoekopdracht is het gelijkheidsgedeelte tag:..., letterId:...
en het sorteergedeelte is emailId:-1
. Er is geen bereikgedeelte in uw zoekopdracht.
Als u dit patroon gebruikt, is de samengestelde index die u nodig hebt:
db.test.createIndex({tag:1, letterId:1, emailId:-1})
Laten we proberen te bevestigen hoeveel prestatieverbetering we kunnen krijgen met deze index.
Testgegevens
Om de geschiktheid van de index te bevestigen, heb ik 1 miljoen records in een testdatabase ingevoegd met behulp van mgeneratejs , een hulpmiddel om een willekeurig document te maken met behulp van een sjabloon.
Gebaseerd op uw voorbeeld, de mgeneratejs
sjabloon die ik gebruik is:
$ cat template.json
{
"emailId": "$hash",
"email": "$email",
"letterId": "$hash",
"sendedFrom": "$email",
"resultMsg": "$word",
"owner": "$name",
"created": "$date",
"result": "$bool",
"tag": "$word",
"tryNum": {"$integer": {"min": 0, "max": 1e3}},
"clickHash": "$word",
"links": {"$array": {"of": "$url", "number": {"$integer": {"min": 1, "max": 5}}}}
}
en importeerde 1 miljoen willekeurige documenten in MongoDB:
$ mgeneratejs template.json -n 1000000 | mongoimport -d test -c test
Test 1:niet-optimale index
Vervolgens maak ik de index die je hebt, en probeerde een niet-bestaand document te vinden en verzamelde 10 runs van de query met de verzameling die alleen deze index bevat:
> db.test.createIndex({emailId: 1, letterId: 1, result: 1, owner: 1, tag: 1, clickHash: 1})
> db.test.find({"tag" : "xyz", "letterId" : "abc"}).sort({emailId: -1}).limit(1)
Fetched 0 record(s) in 3069ms
Fetched 0 record(s) in 2924ms
Fetched 0 record(s) in 2923ms
Fetched 0 record(s) in 3013ms
Fetched 0 record(s) in 2917ms
Fetched 0 record(s) in 2961ms
Fetched 0 record(s) in 2882ms
Fetched 0 record(s) in 2870ms
Fetched 0 record(s) in 2969ms
Fetched 0 record(s) in 2863ms
dus als je die index gebruikt, zijn de responstijden van de query niet geweldig, met de meeste uitvoeringen in de buurt van 3 seconden.
Test 2:gelijkheid -> sorteren -> bereikindex
Door het toevoegen van de optimale gelijkheid -> sorteren -> bereik index:
> db.test.createIndex({tag:1, letterId:1, emailId:-1})
> db.test.find({"tag" : "xyz", "letterId" : "abc"}).sort({emailId: -1}).limit(1)
Fetched 0 record(s) in 2ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 3ms
Bij gebruik van de optimale index werden de prestaties daarentegen aanzienlijk verbeterd. Geen enkele zoekopdracht wordt binnen 3 ms geretourneerd, en in de meeste gevallen wordt deze binnen 1 ms geretourneerd.