sql >> Database >  >> NoSQL >> MongoDB

Waarom zijn inserts traag in de 2.6 MongoDB-shell in vergelijking met eerdere versies?

Vóór 2.6 liep de interactieve shell door de lus en controleerde alleen het succes (met behulp van getLastError) van de laatste bewerking in de lus (meer specifiek, het noemde getLastError na elke regelterugloop, waarbij de laatste bewerking de laatste invoeging in de lus is). Met 2.6 controleert de shell nu de status van elke afzonderlijke bewerking binnen de lus. Dat betekent in wezen dat de "traagheid" met 2.6 kan worden toegeschreven aan erkende versus niet-erkende schrijfprestaties in plaats van een daadwerkelijk prestatieprobleem op zich.

Erkende schrijfbewerkingen zijn de standaard al een tijdje , en dus denk ik dat het gedrag in de 2.6 correcter is, hoewel een beetje lastig voor degenen onder ons die gewend zijn aan het oorspronkelijke gedrag.

Om terug te keren naar uw eerdere prestatieniveaus is het antwoord het gebruik van de nieuwe ongeordende API voor bulkinvoeging . Hier is een getimede versie:

> 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

Dat is nu terug naar in wezen dezelfde prestaties op iets meer dan 2 seconden. Natuurlijk, het is een beetje omvangrijker (excuseer de woordspeling), maar je weet precies wat je krijgt, wat volgens mij in het algemeen een goede zaak is. Er is hier ook een voordeel als u niet op zoek bent naar timinginformatie. Laten we daar vanaf komen en de insert opnieuw uitvoeren:

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

Nu krijgen we een mooi resultaatdocument wanneer we de bulk invoegen, in plaats van alleen de laatste bewerkingen te controleren (de rest in de 2.4-versie was in wezen verzenden en vergeten). Omdat het een ongeordende bulkbewerking is, wordt deze voortgezet als er een fout optreedt en wordt over elke fout in dit document gerapporteerd. In het bovenstaande voorbeeld zijn er geen te zien, maar het is gemakkelijk om kunstmatig een faalscenario te creëren. Laten we vooraf een waarde invoeren waarvan we weten dat deze zal verschijnen en dus een dubbele sleutelfout zal veroorzaken op de (standaard) unieke _id-index:

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

Nu kunnen we zien hoeveel er succesvol waren, welke niet (en waarom). Het is misschien wat ingewikkelder om in te stellen, maar over het algemeen vind ik het een verbetering.

Met dat alles gezegd, en de nieuwe voorkeursmanier geschetst, is er een manier om de shell terug te dwingen naar de legacy-modus. Dit is logisch, aangezien een 2.6-shell mogelijk verbinding moet maken met en werken met oudere servers. Als u verbinding maakt met een 2.4-server, wordt dit voor u geregeld, maar om de zaak voor een bepaalde verbinding te forceren, kunt u het volgende uitvoeren:

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

Als u klaar bent, kunt u teruggaan naar de 2.6-versie met:

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

Voor daadwerkelijk gebruik, zie mijn crud.js-fragment . Dit werkt voorlopig, maar kan in de toekomst zonder voorafgaande kennisgeving worden verwijderd en is echt niet bedoeld voor uitgebreid gebruik, dus gebruik op eigen risico.




  1. Operationele factoren om te overwegen tijdens MongoDB-gegevensmodellering

  2. Hoe push je naar een MongoDB-array met AngularJS?

  3. Vind duplicaat in array zonder $unwind

  4. Hoe redis.conf opslaan en afsluiten?