sql >> Database >  >> NoSQL >> MongoDB

Mongo-query duurt lang. Hoe maak je het sneller?

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.



  1. mongodb-gesprekssysteem

  2. Database.yml verwijderen bij gebruik van Mongoid in Rails 3.2

  3. Maak een mongo-verbinding en maak deze tot leven voor uitvoering van een volledige testsuite in Ready!API

  4. Demeteorizer met node-webkit