sql >> Databáze >  >> NoSQL >> MongoDB

Mongo dotaz trvá dlouho. Jak to udělat rychleji?

Index by musel pokrýt celou část dotazu (část rovnosti, část řazení a část rozsahu). Je to proto, že v typickém find() dotaz, MongoDB používá pouze jeden index. Například obecně nepoužívá jeden index pro část rovnosti a další index pro část řazení.

Obecně platí, že sekvence polí v indexu musí odpovídat vzoru rovnost -> řazení -> rozsah .

To je podrobně popsáno v Optimalizace složených indexů MongoDB .

Pro váš dotaz je část rovnosti tag:..., letterId:... a část řazení je emailId:-1 . Ve vašem dotazu není žádná část rozsahu.

Pomocí tohoto vzoru potřebujete složený index:

db.test.createIndex({tag:1, letterId:1, emailId:-1})

Pokusme se potvrdit, jak velké zlepšení výkonu můžeme dosáhnout pomocí tohoto indexu.

Testovací údaje

Abych potvrdil vhodnost indexu, vložil jsem 1 milion záznamů do testovací databáze pomocí mgeneratejs , což je nástroj pro vytvoření náhodného dokumentu pomocí šablony.

Na základě vašeho příkladu mgeneratejs šablona, ​​kterou používám, je:

$ 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}}}}
}

a importoval 1 milion náhodných dokumentů do MongoDB:

$ mgeneratejs template.json -n 1000000 | mongoimport -d test -c test

Test 1:Neoptimální index

Poté vytvořím index, který máte, a pokusil jsem se najít neexistující dokument a shromáždil 10 spuštění dotazu s kolekcí obsahující pouze tento index:

> 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

takže při použití tohoto indexu nejsou doby odezvy dotazu skvělé, většina provedení se blíží 3 sekundám.

Test 2:rovnost -> řazení -> index rozsahu

Přidáním optimální rovnost -> řazení -> rozsah 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

Naproti tomu při použití optimálního indexu se výkon výrazně zlepšil. Žádný dotaz se nevrátí za více než 3 ms, přičemž ve velké většině případů se vrátí za 1 ms.



  1. MongoDB $ sekunda

  2. Podporuje Spring Data MongoDB funkci řazení MongoDB 3.4?

  3. redis slave se nesynchronizuje s masterem

  4. Příkaz MongoDB dropIndexes