sql >> Databasteknik >  >> NoSQL >> MongoDB

Varför är insättningar långsamma i 2.6 MongoDB-skalet jämfört med tidigare versioner?

Före 2.6 körde det interaktiva skalet genom slingan och kontrollerade bara framgången (med hjälp av getLastError) för den sista operationen i slingan (mer specifikt kallade den getLastError efter varje vagnretur, där den sista operationen är den sista insättningen i slingan). Med 2.6 kommer skalet nu att kontrollera statusen för varje enskild operation i slingan. Det betyder i huvudsak att "långsamheten" med 2.6 kan tillskrivas bekräftad kontra obekräftad skrivprestanda snarare än ett faktisk prestandaproblem i sig.

Erkända skrivningar har varit standardinställningen ett tag nu , och därför tror jag att beteendet i 2.6 är mer korrekt, även om det är lite obekvämt för de av oss som är vana vid det ursprungliga beteendet.

För att komma tillbaka till dina tidigare prestandanivåer är svaret att använda den nya oordnat bulkinsert API . Här är en tidsinställd version:

> 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

Det är nu tillbaka till i stort sett samma prestanda på drygt 2 sekunder. Visst, det är lite mer skrymmande (ursäkta ordleken), men du vet exakt vad du får, vilket jag tycker är bra i allmänhet. Det finns också en uppsida här, när du inte letar efter tidsinformation. Låt oss bli av med det och kör insatsen igen:

> 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 får vi ett snyggt resultatdokument när vi gör bulkinfogningen, snarare än en kontroll av bara de senaste operationerna (alla övriga i 2.4-versionen var i princip skicka och glömma). Eftersom det är en oordnad massoperation kommer den att fortsätta om den stöter på ett fel och rapportera om varje sådant fel i detta dokument. Det finns inga att se i exemplet ovan, men det är lätt att på konstgjord väg skapa ett misslyckande scenario. Låt oss bara förinsätta ett värde som vi vet kommer att komma upp och därför orsaka ett dubblettnyckelfel på det (standard) unika _id-indexet:

> 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 kan vi se hur många som lyckades, vilken som misslyckades (och varför). Det kan vara lite mer komplicerat att installera, men överlag tycker jag att det är en förbättring.

Med allt detta sagt, och det nya föredragna sättet som beskrivs, finns det ett sätt att tvinga tillbaka skalet till äldre läge. Detta är vettigt, eftersom ett 2.6-skal kanske måste ansluta till och fungera med äldre servrar. Om du ansluter till en 2.4-server kommer detta att skötas åt dig, men för att tvinga fram saken för en viss anslutning kan du köra:

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

När du är klar kan du återgå till 2.6-versionen med:

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

För faktisk användning, se mitt crud.js-kodavsnitt . Detta fungerar för tillfället, men kan tas bort utan förvarning när som helst i framtiden och är egentligen inte avsett för omfattande användning, så använd på egen risk.




  1. Mongoose får dokument som matchar arrayen

  2. Ta bort gamla poster i mongodb baserat på månad

  3. Django admin och MongoDB, överhuvudtaget möjligt?

  4. Hur sorterar man en samling efter datum i MongoDB?