首页 > 解决方案 > Mongoose find() 在大型文档上运行缓慢

问题描述

此查询永远不会完成:

   const stocks = await mongoose.model("stock").find().exec();
    console.log(stocks.length);

此查询在 < 1 秒内执行

   const stocks = await mongoose.model("stock").find().select("ticker").exec();
    console.log(stocks.length);

我有很多关于每只股票的数据(10 年的股票数据)。

猫鼬在做什么?对每个发现进行一些验证?我可以使用某些设置将其关闭?

或者是使用 mongodb native 的唯一选择?

更新:

好的所以我试着用 mongo native 代替:

console.log("start");
    const MongoClient = mongodb.MongoClient;
    await MongoClient.connect(connectionMongoUrl, (err, db) => {
      if (err != null) {
        console.log(err);
        return Promise.reject(err);
      }
      const dbo = db.db("tradestats");
      dbo
        .collection("stocks")
        .find({})
        .toArray(async function (err, stocks) {
          console.log(stocks.length); // never fires

同样的问题!它永远不会结束。所以那不是猫鼬。会是什么?nodejs中的一些内存设置还是什么?

更新2:

它是糟糕的数据模型设计吗?错误的数据库?是否应该将 10 年的股票价格放在单独的集合中并使用参考?

标签: mongodb

解决方案


猫鼬在做什么?对每个发现进行一些验证?我可以使用某些设置将其关闭?

简而言之:它做了很多不同的事情。有一篇关于 find() 细节的好文章;

10 年的库存数据很多。我认为您没有为您的用例使用正确的数据库。MongoDB 不是为这类用例而设计的。它是一个面向文档的数据库,你应该这样对待它。对于这种用例,我强烈推荐基于列的数据库。Cassandra 可能是一个不错的选择。如果您需要扩展的话,另一个更复杂的解决方案可能是 hadoop 文件系统上的 Apache ORC。

您也可以尝试增加超时设置,使其不会超时。它不会提高性能,但至少您的查询不会失败。MongoDB 需要遍历所有这些文档并获取所需的信息。如果没有索引,可能会导致性能不佳。因此,添加索引可能会有所帮助。MongoDB 的另一个性能改进可能是使用聚合管道Map Reduce。限制内存使用。


推荐阅读