【问题标题】:How to improve the performance of this MongoDB / Mongoose query?如何提高这个 MongoDB / Mongoose 查询的性能?
【发布时间】:2018-07-03 23:32:54
【问题描述】:

我有一个 GET all products 端点,它需要很长时间才能返回响应:

Product.find(find, function(err, _products) {
  if (err) {
    res.status(400).json({ error: err })
    return
  }

  res.json({ data: _products })

}).sort( [['_id', -1]] ).populate([
  { path: 'colors', model: 'Color' },
  { path: 'size', model: 'Size' },
  { path: 'price', model: 'Price' }
]).lean()

尽管 products 集合中只有 60 个文档,但此查询最多需要 4 秒

这个查询来自以前的开发者,我对 Mongoose 不是很熟悉。

sortpopulate 的性能后果是什么?我认为populate 应该归咎于此?我不太确定 populate 在做什么,所以我不清楚如何避免它或在数据库级别建立索引以提高性能。

【问题讨论】:

  • 您可以通过 db.products.createIndex({'_id': '-1''}); 创建索引,但我怀疑这就是问题所在,它很可能是 populate 完成的“连接”,这正在消耗能量。在链的末端使用explain() 也可能会有所帮助。
  • 感谢explain()的提示

标签: javascript node.js mongodb mongoose nosql


【解决方案1】:

来自Mongoose 文档,“填充是用其他集合中的文档自动替换文档中指定路径的过程”

因此,model 上的 ObjectId 引用将被整个 Mongoose document 替换。因此,在一个query 中对多个路径执行此操作会降低您的应用程序的速度。如果要保持相同的代码结构,可以使用select 指定应填充document 的哪些字段,即{ path: 'colors', model: 'Color', select: 'name' }。所以这里不是返回Colordocument的所有数据,而是得到名称。

您也可以调用cursor() 以流式传输来自MongoDBquery 结果:

var cursor = Person.find().cursor();
cursor.on('data', function(doc) {
  // Called once for every document
});
cursor.on('close', function() {
  // Called when done
});

您可以在Mongoose 文档here 中阅读有关cursor function 的更多信息。

一般来说,尽量只将populate 用于特定任务,例如仅获取一种产品的颜色名称。

sort 不会导致任何重大的性能问题,直到您访问更大的数据库。

希望对你有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 2014-07-17
    • 1970-01-01
    • 2012-04-10
    • 2017-04-12
    • 1970-01-01
    相关资源
    最近更新 更多