【问题标题】:Very slow update performance更新速度非常慢
【发布时间】:2016-05-03 12:19:24
【问题描述】:

我正在解析一个 CSV 文件,对于每一行我想检查数据库中是否存在相应的条目,如果存在我想更新它,如果不存在我想输入一个新条目。

它非常慢 - 每秒只有大约 30 个条目。

我是不是做错了什么?

使用node、mongodb、mongo

 function loadShopsCSV(ShopsName) {
    var filename = 'test.csv'

        csv
            .fromPath(filename)
            .on("data", function(data) {               
                           var entry = {
                                PeriodEST: Date.parse(data[0]),
                                TextDate: textDateM,
                                ShopId: parseInt(data[1]),
                                ShopName: data[2],
                                State: data[3],
                                AreaUS: parseInt(data[4]),
                                AreaUSX: AreaUSArray[stateArray.indexOf(data[3])],
                                ProductClass: data[5],
                                Type: data[6],
                                SumNetVolume: parseInt(data[7]),                                
                                Weekday: weekdayNum,                              
                                WeightedAvgPrice: parseFloat(data[8]),

                            }


                            db.get(ShopsDBname).update(
                                {"PeriodEST" : entry.PeriodEST,
                                 "ShopName": entry.ShopName,
                                 "State" : entry.State,
                                 "AreaUS" : entry.AreaUS,
                                 "ProductClass" : entry.ProductClass,
                                 "Type" : entry.Type},
                                  {$set : entry},
                                  function(err, result) {

                                  }
                            );
                    }
                }
            })
            .on("end", function() {
                console.log('finished loading: '+ShopsName)
            });
    }, function(err) {
        console.error(err);
    });
}

【问题讨论】:

    标签: node.js mongodb monk


    【解决方案1】:

    首先我建议本地化问题:

    • .on("data", function(data)替换为虚拟.on("data", function() {return;}),确认csv解析速度。
    • 打开mongo profilerdb.setProfilingLevel(1),如果有任何查询慢于100毫秒,请检查慢日志。

    如果以上没有问题 - 瓶颈在于您用于准备和发送查询的 nodejs 库之一。

    假设问题出在缓慢的 mongodb 查询上,您可以使用explain 进行更新查询以获取详细信息。可能是它不使用任何索引并为每次更新运行表扫描。

    最后,推荐使用bulk 操作,它专为您的用例而设计。

    【讨论】:

    • 我所有的更新查询都需要超过 100 毫秒 - 我可以在 mongo 控制台中看到它。我找不到任何通过批量方式逐个更新元素的示例...
    • 不幸的是和尚还不支持批量API:github.com/Automattic/monk/issues/85
    • 快速搜索返回风帆示例:*.com/questions/32019267/…
    • 如果不能更改库,则需要分析数据库性能。第一步是用db.YourCollection.explain().update(....typical update query...)的结果更新问题
    • 我不知道它的作用或含义,但是在我通过 db.shops.createIndex(("PeriodEST":1 .. 查询的字段上添加索引后,它的速度显着加快
    【解决方案2】:

    您是否尝试过不考虑写入问题的更新?因为 MongoDB 阻塞直到整个更新成功并且 DB 发回该确认?你在集群上还是什么? (如果是这样,可能想写入主节点)

    在您的 {$set : entry} 之后, {writeConcern:{w:0}}

    【讨论】:

    • 我认为和尚驱动只需要两个参数,在这种情况下,users.update({}, {}, fn); 所以我无处传递 writeconcern 参数。如果我在 fn 之前添加一个额外的参数,它将被忽略。