sql >> データベース >  >> NoSQL >> MongoDB

2.6 MongoDBシェルでの挿入が以前のバージョンと比較して遅いのはなぜですか?

    2.6より前では、インタラクティブシェルはループを実行し、ループ内の最後の操作(より具体的には、 getLastError 各キャリッジリターンの後、最後の操作がループの最後の挿入になります)。 2.6では、シェルはループ内の個々の操作のステータスをチェックするようになりました。基本的に、2.6の「速度低下」は、実際のパフォーマンスの問題自体ではなく、確認済みの書き込みパフォーマンスと未確認の書き込みパフォーマンスに起因する可能性があることを意味します。

    承認された書き込みは、defaultです。しばらくの間 、したがって、2.6の動作はより正確だと思いますが、元の動作に慣れている私たちにとっては少し不便です。

    以前のレベルのパフォーマンスに戻すには、新しい順序付けされていない一括挿入API 。これが時限バージョンです:

    > 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
    

    これで、2秒強で基本的に同じパフォーマンスに戻ります。確かに、それはもう少しかさばります(しゃれを許してください)が、あなたはあなたが何を得ているかを正確に知っています、それは一般的に良いことだと思います。タイミング情報を探していない場合は、ここにも利点があります。それを取り除き、挿入をもう一度実行しましょう:

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

    これで、最後の操作だけをチェックするのではなく、一括挿入を実行すると、優れた結果ドキュメントが得られます(2.4バージョンの残りはすべて送信されて忘れられました)。これは順序付けられていない一括操作であるため、エラーが発生した場合は続行し、このドキュメントでそのような各エラーについて報告します。上記の例には見られるものはありませんが、障害シナリオを人為的に作成するのは簡単です。表示されることがわかっている値を事前に挿入して、(デフォルトの)一意の_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" : [ ]
    })
    

    これで、成功したものと失敗したもの(およびその理由)を確認できます。設定は少し複雑かもしれませんが、全体的には改善されたと思います。

    以上のことをすべて踏まえ、新しい推奨方法の概要を説明すると、シェルを強制的にレガシーモードに戻す方法があります。 2.6シェルは古いサーバーに接続して動作する必要があるため、これは理にかなっています。 2.4サーバーに接続する場合、これは自動的に処理されますが、特定の接続の問題を強制するために実行できます:

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

    完了したら、次のコマンドを使用して2.6バージョンに戻すことができます。

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

    実際の使用法については、私のcrud.jsスニペット> 。これは今のところ機能しますが、将来のいずれかの時点で予告なしに削除される可能性があり、実際には広範囲に使用することを意図していないため、自己責任で使用してください。




    1. スキーマの再帰要素:マングースモデリング

    2. HBase:低メモリEC2で実行するための5つのヒント

    3. mongodbで日付形式を変換する方法

    4. Redisクライアント