当没有文档匹配并且可以更改时,为什么MongoDB update()比find()慢?

时间:2019-06-15 03:10:07

标签: mongodb performance

请考虑以下两种(可能)更新一堆记录的方法:

方法1(“查找并可能更新”):

<html>
<head></head>
<body>
<iframe src="exam.com/gg.html"></iframe>
</body>
</html>

方法2(“直接更新”):

let ids = db.getCollection("users").find({
    "status.lastActivity": {"$lte": timeoutDate}
}, {
    "fields": {"_id": 1}
}).fetch().map(doc => {
    doc = doc._id;
    return doc
});

if (ids.length) {
    db.getCollection("users").update({
        "_id": {"$in": ids}
    }, {
        "$set": {
            "status.idle": true
        }
    }, {
        "multi": true
    });
}

现在,为了简单起见,我们假设db.getCollection("users").update({ "status.lastActivity": {"$lte": timeoutDate} }, { "$set": { "status.idle": true } }, { "multi": true }); 的用户永远比status.lastActivity小(因此timeoutDate总是空数组)。

在这种情况下,使用方法1可以获得显着的更好的性能。例如方法1花费0.1到2毫秒,而方法2花费40到80毫秒。

我现在的问题是,为什么会这样?我本来以为MongoDB足够“聪明”,可以在我实际使用方法2时在后台执行类似于方法1的操作,并且在选择器实际上没有匹配的记录时也不会浪费资源...

我可以以某种方式更改它,以便它那样工作吗?还是我可能是某种错误的配置导致了这种情况,而我却可以摆脱呢?因为显然在“方法2”中编写类似的东西会更精简...

1 个答案:

答案 0 :(得分:0)

这是JS中的吗? db.getCollection("users").find(看起来应该返回一个Promise,并且Promise没有长度,因此由ids.length控制的更新代码将永远不会运行。