我一直在测试MongoDB的限制,看看它是否适用于即将推出的项目,而且我注意到与插入相比,upserts相当慢。
当然,我预计它们会变慢,但不会(几乎)慢一个数量级(7400 vs 55000 ops / sec)。这是我使用的(nodejs本机驱动程序)基准测试代码:
(async function() {
let db = await require('mongodb').MongoClient.connect('mongodb://localhost:27017/mongo-benchmark-8764824692947');
db.collection('text').createIndex({text:1},{unique:true})
let batch = db.collection('text').initializeOrderedBulkOp();
let totalOpCount = 0;
let batchOpCount = 0;
let start = Date.now();
while(1) {
totalOpCount++;
batchOpCount++;
if(batchOpCount === 1000) { // batch 1000 ops at a time
await batch.execute();
batch = db.collection('text').initializeOrderedBulkOp();
batchOpCount = 0;
let secondsElapsed = (Date.now() - start)/1000;
console.log(`(${Math.round(totalOpCount/secondsElapsed)} ops per sec) (${totalOpCount} total ops)`)
}
///////// INSERT TEST ///////// (~55000 ops/sec)
// batch.insert({text:totalOpCount});
///////// UPSERT TEST ///////// (~7400 ops/sec)
let text = Math.floor(Math.random()*1000000);
batch.find({text}).upsert().updateOne({$setOnInsert:{text}});
if(totalOpCount > 500000) {
console.log("<< finished >>");
await db.dropCollection('text');
db.close();
break;
}
}
})();
您可以通过将其粘贴到index.js
,运行npm init -y
和npm install --save mongodb
然后node .
当我们upsert
文档时,mongo引擎必须检查是否存在与之匹配的现有文档。这可能解释了一些减速,但是对于唯一索引的insert
命令是否需要相同的冲突检查?谢谢!
修改结果显示$setOnInsert
,否则我们会收到重复的密钥错误。
答案 0 :(得分:0)
我通过将if(batchOpCount === 1000)
更改为if(batchOpCount === 50000)
来使每个批次更大,并为insert
获得〜 90000 操作/秒,并且〜 35000 upsert
的强>操作/秒。我不确定为什么批量大小会产生相对的差异。有意义的是,较小的批次会导致较少的操作/秒(通信开销),但我不确定为什么upserts
会超过inserts
,尽管这可能是一个单独问题的主题。
这个(大致)3倍的速度差异肯定更接近我期望的两个操作之间的性能差异,但似乎upserts
似乎比它们应该慢一点,鉴于insert还必须检查冲突(由于唯一索引)。这真的只是一个半答案,所以我打开这个问题,希望mongo pro会出现并提供更完整的答案。