Node.js Nodejs Mongodb查找性能问题

Node.js Nodejs Mongodb查找性能问题,node.js,mongodb,promise,mongodb-query,Node.js,Mongodb,Promise,Mongodb Query,我最近刚接触到mongodb,那时我已经有很多问题了。我正在制作一款纸牌游戏,所以我认为mongodb是最好的选择 现在我正试图找到我所有的牌组、手牌和桌牌,问题是执行起来需要很长时间,即使收集量很小 e、 g fetch函数是这样的,当然mongoClient连接不是一个好办法,但我只是使用这个函数进行测试 const getDeckCards = (gameid) =>{ return new Promise ((resolve,reject) => { c

我最近刚接触到mongodb,那时我已经有很多问题了。我正在制作一款纸牌游戏,所以我认为mongodb是最好的选择

现在我正试图找到我所有的牌组、手牌和桌牌,问题是执行起来需要很长时间,即使收集量很小

e、 g

fetch函数是这样的,当然mongoClient连接不是一个好办法,但我只是使用这个函数进行测试

const getDeckCards =  (gameid) =>{
    return new Promise ((resolve,reject) => {
      console.time("deck");
    MongoClient.connect(url, { useNewUrlParser: true }, function (err, client) {
    const db = client.db(dbName);
    const collection = db.collection("deck");
    resolve(collection.find({ gameID: gameid }).project({ _id: 0, gameID: 0 }).toArray());
    });
    console.timeEnd("deck");
  });
  }

  const getHandCards =  (userid) =>{
    return new Promise ((resolve,reject) => {
      console.time("hand");
    MongoClient.connect(url, { useNewUrlParser: true }, function (err, client) {
      const db = client.db(dbName);
    const collection = db.collection("hand");
    resolve(collection.find({ userID: userid }).project({ _id: 0, userID: 0 }).toArray());
    });
    console.timeEnd("hand");
  });
  }

  const getTableCards =  (gameid) =>{

    return new Promise ((resolve,reject) => {
      console.time("table");
    MongoClient.connect(url, { useNewUrlParser: true }, function (err, client) {
      const db = client.db(dbName);
    const collection = db.collection("table");
    resolve(collection.find({ gameID: gameid }).project({ _id: 0, gameID: 0 }).toArray());
    });
    console.timeEnd("table");
  });
  }
我试图得到所有的承诺,然后将它们作为数组返回

const initGame = (async() => {
    console.time("init");
   let [deck,hand,table] = await Promise.all([
      getDeckCards("aasd12"),
      getHandCards(1),
      getTableCards("aasd12")
    ])

    console.timeEnd("init");
    return [deck[0],hand[0],table[0]];
  });
它显示了deck、hand和table函数非常快,这是我希望得到的结果,但是整个结果需要1秒,对于这样小的查询来说,这是非常慢的

deck: 12.235ms
hand: 1.977ms
table: 0.534ms
init: 1058.646ms

我做错了什么?是promise all函数需要很长时间才能执行,还是我的Mongodb查询有问题?

问题是每次都要创建一个到mongo的新连接

解决方案是创建单个连接并保持其活动状态,并在不再需要时(当应用程序停止时)将其关闭

此示例代码肯定会对您的性能产生良好的影响:

class GameManager {
  constructor() {
    this.mongoClient = null;
  }

  async connect(dbName) {
    this.mongoClient = await MongoClient.connect(url, { useNewUrlParser: true });
    this.db = this.mongoClient.db(dbName);
  }

  getDeckCards(gameId) {
    if (!this.mongoClient) {
      return Promise.reject();
    }

    return this.db.collection("deck")
      .find({ gameID: gameId })
      .project({ _id: 0, gameID: 0 })
      .toArray();
  }
}

const initGame = () => {
  console.time("init");
  const gameManager = new GameManager();
  return gameManager.connect(dbName)
    .then(() => {
      return Promise.all([
        getDeckCards("aasd12"),
        getHandCards(1),
        getTableCards("aasd12")
      ])
    })
    .then(() => {
      console.timeEnd("init");
    });
};

还记得在mongo上为您搜索的字段创建索引(例如本例中的
gameID
)。通过这种管理,您可以更快地访问数据。

主要问题是,您正在为每个函数调用创建一个新的数据库连接,这非常低效。创建一次连接(
MongoClient
instance),然后重用它。另外,您没有正确计时(
console.timeEnd
应该在调用
resolve
后添加,但在同一范围内)。每次创建新连接和调用
toArray
都很昂贵。我们在这里谈论的唱片数量是多少?谢谢你的回答,非常感谢你抽出时间来回答这个问题。我尝试了你的代码,但奇怪的是结果是一样的:当尝试添加索引时,init time=1060.204ms,例如this.db.collection(“deck”).createIndex({“deckData”:1});它需要更长的初始时间=2078.974ms。我还认为在我的ubuntu子系统中使用mongod可能会有问题,但当直接在我的Windows 10上安装时,情况并非如此。初始化时间总是很慢,因为你必须建立到DB的连接。你查过查询中的时间了吗?因为我的期望是queryes(
getDeckCards,getHandCards,getTableCards
)大约为毫秒。验证延迟的另一种方法是使用非常简单的bubbleprof(),只需运行
clinic bubbleprof-node yourscript.js
class GameManager {
  constructor() {
    this.mongoClient = null;
  }

  async connect(dbName) {
    this.mongoClient = await MongoClient.connect(url, { useNewUrlParser: true });
    this.db = this.mongoClient.db(dbName);
  }

  getDeckCards(gameId) {
    if (!this.mongoClient) {
      return Promise.reject();
    }

    return this.db.collection("deck")
      .find({ gameID: gameId })
      .project({ _id: 0, gameID: 0 })
      .toArray();
  }
}

const initGame = () => {
  console.time("init");
  const gameManager = new GameManager();
  return gameManager.connect(dbName)
    .then(() => {
      return Promise.all([
        getDeckCards("aasd12"),
        getHandCards(1),
        getTableCards("aasd12")
      ])
    })
    .then(() => {
      console.timeEnd("init");
    });
};