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

Proč jsou vložení pomalé v prostředí 2.6 MongoDB ve srovnání s předchozími verzemi?

Před verzí 2.6 by interaktivní shell procházel smyčkou a pouze kontroloval úspěšnost (pomocí getLastError) poslední operace ve smyčce (konkrétněji se jmenovala getLastError po každém návratu vozíku, přičemž poslední operace je poslední vložení do smyčky). S verzí 2.6 bude nyní shell kontrolovat stav každé jednotlivé operace v rámci smyčky. V podstatě to znamená, že „pomalost“ u verze 2.6 lze připsat spíše potvrzenému a nepotvrzenému výkonu zápisu než skutečnému problému s výkonem jako takovým.

Potvrzené zápisy byly výchozí už nějakou dobu , a tak si myslím, že chování ve 2.6 je správnější, i když trochu nepohodlné pro ty z nás, kteří jsme zvyklí na původní chování.

Chcete-li se vrátit k předchozím úrovním výkonu, odpovědí je použití nového rozhraní API pro neuspořádané hromadné vkládání . Zde je časovaná verze:

> 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

To je nyní zpět k v podstatě stejnému výkonu za něco málo přes 2 sekundy. Jistě, je to trochu objemnější (promiňte, ale víte přesně, co dostáváte, což si myslím, že je obecně dobrá věc. Je zde také výhoda, když nehledáte informace o načasování. Pojďme se toho zbavit a spusťte vložku znovu:

> 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" : [ ]
})

Nyní dostáváme pěkný výsledný dokument, když provádíme hromadné vkládání, spíše než kontrolu pouze posledních operací (všechny ostatní ve verzi 2.4 byly v podstatě odeslány a zapomenout). Protože se jedná o neuspořádanou hromadnou operaci, bude pokračovat, pokud dojde k chybě, a bude o každé takové chybě hlásit v tomto dokumentu. Ve výše uvedeném příkladu nejsou žádné vidět, ale je snadné uměle vytvořit scénář selhání. Předem vložte hodnotu, o které víme, že se objeví, a proto způsobí chybu duplicitního klíče na (výchozím) jedinečném indexu _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" : [ ]
})

Nyní můžeme vidět, kolik z nich bylo úspěšných, který z nich selhal (a proč). Nastavení může být trochu složitější, ale celkově si myslím, že jde o zlepšení.

Se vším, co bylo řečeno, a nastíněným novým preferovaným způsobem, existuje způsob, jak přinutit shell zpět do staršího režimu. To dává smysl, protože shell 2.6 se možná bude muset připojit ke starším serverům a pracovat s nimi. Pokud se připojíte k serveru 2.4, bude o to postaráno za vás, ale pro vynucení záležitosti pro konkrétní připojení můžete spustit:

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

Jakmile budete hotovi, můžete se vrátit zpět k verzi 2.6 pomocí:

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

Skutečné použití naleznete v mém úryvku crud.js . Toto zatím funguje, ale může být kdykoli v budoucnu bez upozornění odstraněno a opravdu není určeno pro rozsáhlé použití, takže jej používejte na vlastní riziko.




  1. Skript Redis lua nefunguje

  2. Rozdíl mezi zdobením vlastnosti v C# pomocí BsonRepresentation(BsonType.ObjectId) vs BsonId vs ObjectId

  3. Šifrování databáze MongoDB

  4. Řazení podle relevance pomocí MongoDB