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

Dlaczego wstawianie jest powolne w powłoce MongoDB 2.6 w porównaniu z poprzednimi wersjami?

Przed wersją 2.6 interaktywna powłoka działała przez pętlę i sprawdzała tylko powodzenie (przy użyciu getLastError) ostatniej operacji w pętli (dokładniej nazywała się getLastError po każdym powrocie karetki, przy czym ostatnią operacją jest ostatnia operacja wstawienia w pętli). W wersji 2.6 powłoka będzie teraz sprawdzać stan każdej pojedynczej operacji w pętli. Zasadniczo oznacza to, że „powolność” w wersji 2.6 można przypisać potwierdzonej lub niepotwierdzonej wydajności zapisu, a nie samemu problemowi z wydajnością.

Uznane zapisy były domyślnym od jakiegoś czasu , więc myślę, że zachowanie w wersji 2.6 jest bardziej poprawne, choć trochę niewygodne dla tych z nas, którzy są przyzwyczajeni do oryginalnego zachowania.

Aby wrócić do poprzednich poziomów wydajności, odpowiedzią jest użycie nowego interfejs API nieuporządkowanego zbiorczego wstawiania . Oto wersja czasowa:

> db.timecheck.drop();
true
> var bulk = db.timecheck.initializeUnorderedBulkOp(); start = new Date(); for(var i = 0; i < 100000; i++){bulk.insert({"_id" : i})}; bulk.execute({w:1}); end = new Date(); print(end - start);
2246

Teraz wróciłem do zasadniczo tej samej wydajności w nieco ponad 2 sekundy. Jasne, jest trochę bardziej obszerny (przepraszam za kalambur), ale wiesz dokładnie, co dostajesz, co ogólnie uważam za dobrą rzecz. Istnieje również zaleta, gdy nie szukasz informacji o czasie. Pozbądźmy się tego i uruchom wstawkę ponownie:

> db.timecheck.drop();
true
> var bulk = db.timecheck.initializeUnorderedBulkOp(); for(var i = 0; i < 100000; i++){bulk.insert({"_id" : i})}; bulk.execute({w:1});
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 100000,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})

Teraz otrzymujemy ładny dokument wynikowy, gdy wykonujemy zbiorcze wstawianie, zamiast sprawdzania tylko ostatnich operacji (cała reszta w wersji 2.4 była zasadniczo wysyłana i zapominana). Ponieważ jest to nieuporządkowana operacja zbiorcza, będzie kontynuowana w przypadku napotkania błędu i zgłoszenia każdego takiego błędu w tym dokumencie. W powyższym przykładzie nie widać żadnego, ale łatwo jest sztucznie stworzyć scenariusz niepowodzenia. Po prostu wstawmy wstępnie wartość, o której wiemy, że pojawi się i spowoduje błąd zduplikowanego klucza w (domyślnym) unikalnym indeksie _id:

> db.timecheck.drop();
true
> db.timecheck.insert({_id : 500})
WriteResult({ "nInserted" : 1 })
> var bulk = db.timecheck.initializeUnorderedBulkOp(); for(var i = 0; i < 100000; i++){bulk.insert({"_id" : i})}; bulk.execute({w:1});
2014-03-28T16:19:40.923+0000 BulkWriteError({
"writeErrors" : [
{
"index" : 500,
"code" : 11000,
"errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: test.timecheck.$_id_ dup key: { : 500.0 }",
"op" : {
"_id" : 500
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 99999,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})

Teraz możemy zobaczyć, ile się udało, a które zawiodły (i dlaczego). Konfiguracja może być nieco bardziej skomplikowana, ale ogólnie uważam, że jest to poprawa.

Biorąc to wszystko pod uwagę i nakreślono nowy preferowany sposób, istnieje sposób na zmuszenie powłoki do powrotu do trybu starszego. Ma to sens, ponieważ powłoka 2.6 może łączyć się ze starszymi serwerami i pracować ze starszymi serwerami. Jeśli połączysz się z serwerem 2.4, zajmiemy się tym za Ciebie, ale aby wymusić sprawę dla konkretnego połączenia, możesz uruchomić:

db.getMongo().forceWriteMode("legacy");

Gdy skończysz, możesz wrócić do wersji 2.6 za pomocą:

db1.getMongo().forceWriteMode("commands");

Aby zapoznać się z rzeczywistym użyciem, zobacz mój fragment crud.js . To działa na razie, ale może zostać usunięte bez powiadomienia w dowolnym momencie w przyszłości i tak naprawdę nie jest przeznaczone do intensywnego użytkowania, więc używaj go na własne ryzyko.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Metoda MongoDB Date()

  2. mongodb zapytania zarówno z AND i OR

  3. Pole Manytomany w dokumencie Django mongoengine

  4. Wstawianie obiektu momentjs do kolekcji Meteor

  5. MongoDB odpowiednik SQL COUNT GROUP BY