我是MongoDB生态系统的新手,在我的ASP.NET MVC应用程序中使用MongoDB时遇到了问题。如果我只为一个集合调用Find方法,它的工作速度非常快,只需几毫秒。但是如果我使用Task.Run()在同一时刻多次调用Find方法,它会变得非常慢,甚至可能超过30秒超时。
性能下降数字如下:
如果我在不使用任务的情况下一个接一个地运行相同的40个查询,则所有这些查询将在不到一秒钟内完成(~0.7秒),即每次查询相同的~0.002秒。
我已经做了什么而且没有帮助:
无论我是在任务代码中创建连接对象还是在开头创建一次并存储在静态字段中。
无论我以哪种方式查询数据:
collection.AsQueriable().Where(...).Take(1)
collection.Find(Builders<T>.Filter.Eq(...)).FirstOrDefault()
collection.Find(m => ...).FirstOrDefault()
增加超时有助于避免超时异常,但预计性能仍然不佳。
我的环境:
我的MongoDB集合中的数据非常少(21个对象,总共1995个字节,每个对象平均95个字节)。 MongoDB服务器位于localhost环境中,因此网络不是问题。服务器版本为3.2.4,用作Windows服务。我使用Azure中的Linux VM托管的MongoDB获得相同的结果。 .NET MongoDB驱动程序是最后一个并从nuget安装,版本是2.3.0.157。
我无法相信这样一个成熟的系统无法同时处理少量查询。所以我可能错过了一些东西。有人可以帮我指出方向吗?
EDIT。我用于测试的代码示例:
// IMongoDatabase database;
int iterations = 40;
var tasks = new Task<TimeSpan>[iterations];
for (int i = 0; i < iterations; i++) {
var tempI = i;
tasks[i] = new Task<TimeSpan>(() => {
var stopwatch = new Stopwatch();
stopwatch.Start();
var integrationId = INTEGRATION_IDS[tempI];
try {
var metadataCollection = database.GetCollection<CacheMetadata>(METADATA_COLLECTION_NAME);
var query = metadataCollection.AsQueryable()
.Where(m => m.IntegrationId == integrationId)
.Take(1);
var metadata = query.FirstOrDefault();
stopwatch.Stop();
// Write elapsed time to the console
}
catch (Exception ex) {
// Write the exception details to the console
}
return stopwatch.Elapsed;
});
}
for (int i = 0; i < iterations; i++) {
tasks[i].Start();
}
Task.WaitAll(tasks);
// Write summary to the console