MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Zapytanie Mongo zajmuje dużo czasu. Jak przyspieszyć?

Indeks musiałby obejmować całą część zapytania (część dotyczącą równości, część sortowania i część zakresu). Dzieje się tak, ponieważ w typowym find() zapytanie MongoDB używa tylko jednego indeksu. Np. generalnie nie używa jednego indeksu dla części równości i innego indeksu dla części sortowania.

Ogólnie sekwencja pól w indeksie musi być zgodna ze wzorem równość -> sortowanie -> zakres .

Jest to szczegółowo opisane w Optymalizacja indeksów złożonych MongoDB .

W zapytaniu część dotycząca równości to tag:..., letterId:... a część sortowania to emailId:-1 . W zapytaniu nie ma części dotyczącej zakresu.

Używając tego wzorca, potrzebny indeks złożony to:

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

Spróbujmy potwierdzić, jak dużą poprawę wydajności możemy uzyskać za pomocą tego indeksu.

Dane testowe

Aby potwierdzić przydatność indeksu, wstawiłem 1 milion rekordów do testowej bazy danych za pomocą mgeneratejs , który jest narzędziem do tworzenia losowego dokumentu przy użyciu szablonu.

Na podstawie twojego przykładu mgeneratejs szablon, którego używam to:

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

i zaimportowaliśmy 1 milion losowych dokumentów do MongoDB:

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

Test 1:indeks nieoptymalny

Następnie tworzę indeks, który masz, i próbowałem znaleźć nieistniejący dokument i zebrałem 10 przebiegów zapytania z kolekcją zawierającą tylko ten indeks:

> 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

więc używając tego indeksu, czasy odpowiedzi na zapytanie nie są świetne, a większość wykonania jest bliska 3 sekundom.

Test 2:równość -> sortowanie -> indeks zakresu

Dodając optymalną równość -> sortowanie -> zakres indeks:

> 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

W przeciwieństwie do tego, stosując optymalny wskaźnik, wydajność została znacznie poprawiona. Żadne zapytanie nie zostało zwrócone w czasie dłuższym niż 3 ms, przy czym większość czasu jest zwracana w ciągu 1 ms.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Problem z dokładnością czasu w porównaniu w sterowniku mongodb w Go i prawdopodobnie w innym języku i innej bazie danych

  2. Prawidłowy sposób wstawiania wielu rekordów do Mongodb za pomocą Node.js

  3. Uruchamianie wielu zapytań w mongo`

  4. Tworzenie dynamicznego schematu za pomocą mangusty

  5. Wyszukiwanie wartości dowolnego pola w MongoDB bez jawnego nazywania go