Node.js Nodejs Mongodb查找性能问题
我最近刚接触到mongodb,那时我已经有很多问题了。我正在制作一款纸牌游戏,所以我认为mongodb是最好的选择 现在我正试图找到我所有的牌组、手牌和桌牌,问题是执行起来需要很长时间,即使收集量很小 e、 g fetch函数是这样的,当然mongoClient连接不是一个好办法,但我只是使用这个函数进行测试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
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");
});
};