如何查看MongoDB updateOne操作的执行时间
如何获取MongoDB updateOne操作的执行时间并确保操作实际执行?
你在MongoDB 4.0.14中尝试获取updateOne的执行时间时遇到两个问题:一是之前的explain写法无效,二是runCommand explain未实际执行操作。下面是对应的解决方案:
一、为什么runCommand explain没有实际执行操作
MongoDB的explain命令针对写操作(如update)时,默认只是模拟执行过程,不会实际修改或插入数据,所以你看到的wouldInsert: true仅表示操作会执行插入,但不会真的写入数据——这是explain的设计特性,用于在不影响数据的前提下分析执行计划。
二、获取updateOne执行时间的两种正确方式
方式1:用explain获取模拟执行的预估时间(不修改数据)
如果你只需要了解操作的执行计划和预估耗时,使用runCommand结合executionStats verbosity即可,同时修正update语句的写法(避免直接替换整个文档):
db.runCommand( { explain: { update: "Test", updates: [ { q: { "fid": "1111" }, u: { "$set": { "origin": "SKD" } }, // 用$set仅修改指定字段,而非替换整个文档 upsert: true } ] }, verbosity: "executionStats" // 明确指定获取执行统计信息 } )
返回结果中的executionStats.executionTimeMillis就是模拟执行的耗时。
方式2:获取实际执行的真实耗时(会修改数据)
如果需要真实的执行时间,有两种可行方法:
方法A:手动计时(Shell中直接执行)
在MongoDB Shell中手动记录操作前后的时间差:
// 记录开始时间 const startTime = new Date(); // 执行updateOne操作 const result = db.getCollection('Test').updateOne( { "fid": "9999" }, { "$set": { "origin": "SKD" } }, { "upsert": true } ); // 计算并输出耗时 const endTime = new Date(); const executionTime = endTime - startTime; print(`操作结果: ${JSON.stringify(result)}`); print(`实际执行时间: ${executionTime} 毫秒`);
方法B:启用数据库分析器(Profiler)
开启Profiler可以自动记录所有操作的执行细节,包括执行时间:
- 开启分析器(生产环境谨慎使用,会影响性能):
db.setProfilingLevel(2); // 2表示记录所有操作
- 执行你的updateOne操作:
db.getCollection('Test').updateOne( { "fid": "9999" }, { "$set": { "origin": "SKD" } }, { "upsert": true } );
- 查询profiler日志获取执行时间:
db.system.profile.find({ op: "update", ns: "sampledb.Test" }).sort({ ts: -1 }).limit(1).pretty();
返回结果中的millis字段就是实际执行时间。
4. 关闭分析器(可选):
db.setProfilingLevel(0); // 0表示关闭分析器
三、你之前的无效写法问题解析
- 第一种写法:
updateOne(..., {"$explain": 1}),$explain参数仅适用于查询类操作(如find),写操作不支持这种传递方式,因此无有效返回。 - 第二种写法:
explain().updateOne(...),MongoDB 4.0不支持这种链式调用写法,写操作的explain必须通过runCommand实现。
内容的提问来源于stack exchange,提问作者Jet
相关产品推荐
相关产品推荐

