我正在探索 MongoDB,以检查我们是否可以/将把它用作我们产品的 noSQL 存储。
一切似乎都运行良好,但在我们的 C# 应用程序中速度相当慢。查询需要大约 120 到 140 毫秒才能返回结果,这对于我们的应用程序来说是 Not Acceptable (与 MS SQL 相比慢 10 倍)。
起初我认为这可能与$in
有关。运算符和 Guid
我过滤的字段,但事实并非如此。
目前我已经创建了一个小测试来衡量特定查询的性能。该方法如下所示:
public IQueryable<T> QueryTest<T>(string collection, IEnumerable<Guid> shouldBeIn, string fieldName)
{
var dataModelCollection = MongoDatabase.GetCollection<T>(collection);
var findResult = dataModelCollection
.FindAll()
.ToList(); //Doing this on purpose, so the query is executed immediatly. Just for this test!
//This action takes about 110~140ms.
return findResult.AsQueryable();
}
显然这是测试代码,因为我不会使用 ToList()
在真实代码中返回 IQueryable
稍后。
当我在 MongoDB 控制台中运行此查询时,它会在 0 毫秒内返回结果(根据说明)
> db.StoreData.find().explain()
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 21,
"nscannedObjects" : 21,
"nscanned" : 21,
"nscannedObjectsAllPlans" : 21,
"nscannedAllPlans" : 21,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"server" : "mymongodbserver:27017",
"filterSet" : false
}
在 _id
处指定了一个索引领域,也是 StoreId
上的一个字段,因为我想过滤 StoreId
稍后。
C# 和控制台这两个查询都在同一台机器上执行。我也多次运行测试并运行了 .reIndex()
命令也有几次。
关于如何进行的任何想法?
编辑
这是一个非常小的数据库,只有一点点测试数据/记录。按照要求,返回了21条记录,我认为explain()
的结果方法也说明了这一点。
我已经运行了 toArray()
还。我看不出这会有什么帮助,但这是结果的一部分,因为在此处复制 21 个对象可能不是很有帮助。
{
"_id" : ObjectId("542e847e048b8b0f704a7834"),
"StoreId" : BinData(3,"/FQLn0k/hkSofM9WvEsNKQ=="),
"Shelves" : [
{
"ShelveId" : BinData(3,"iCDhfhi6z0adh2haWjrzoQ=="),
"Name" : "Shelve 1",
"Type" : 0
}
],
"Doors" : [ ]
},
{
"_id" : ObjectId("542e847e048b8b0f704a7835"),
"StoreId" : BinData(3,"p7TkqeFrGEOAWtv0RZ4YjQ=="),
"Shelves" : [ ],
"Doors" : [ ]
},
edit2
我在 StoreData
中添加了更多数据collection 来查看返回大量(100.000)文档是更快还是更慢。
在 MongoDB 客户端 ( mongodb.exe
) 中,我得到了巨大的快速结果。
> db.StoreData.find().explain() { "cursor" : "BasicCursor", "isMultiKey" : false, "n" : 100021, "nscannedObjects" : 100021, "nscanned" : 100021, "nscannedObjectsAllPlans" : 100021, "nscannedAllPlans" : 100021, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 781, "nChunkSkips" : 0, "millis" : 53, "server" : "cp-crossbario:27017", "filterSet" : false }
如您所见,在 53 毫秒 内返回了大约 100.000 个结果。
运行 FindAll().ToList()
通过 MongoDB 驱动程序的方法导致在 5075 毫秒 内接收所有文档。完全不同!
关于我运行它的机器的更多背景信息: 我在西欧地区设置了 2 台 Azure Standard_A2 机器(2 核,3.5GB 内存)。
其中一台机器正在运行 MongoDB 数据库。我已经在 C:\MongoDB
上安装了它和 C:\MongoDB\bin\data
上的数据目录.这仅用于测试目的。当然,真正的生产系统不应在此驱动器上安装日期。
测试数据库大小约为 135MB。
在另一台机器上,我安装了测试客户端,控制台应用程序使用 MongoDB C# 驱动程序和 MongoDB.exe。两者都通过相同的 HTTP 端点连接到数据库。
edit3
我刚刚运行了 QueryTest
没有 <T>
的方法,所以现在我要返回“原始”BsonDocument
秒。奇怪的是,它甚至更慢。 100.000 个文档现在需要大约 8000 毫秒才能返回,而返回它们在大约 5000 毫秒内返回的 POCO。
最佳答案
您在 shell 中进行比较的问题在于,当使用 .explain() 运行时,shell 实际上不会拉回任何数据。实际上,您已经消除了整个网络堆栈。所以你看到的 53 毫秒是服务器迭代所有数据所花费的时间。由于您在 Azure 中运行,我很确定网络将占大部分开销。您可以通过同时运行网络捕获并查看 TCP 请求需要多长时间来证明这一点。
还有,查询这么多结果的时候,MongoDB是分批发送的。这意味着它不仅仅是 1 个网络往返。相反,它有很多,每个都会增加时序开销。
关于c# - 使用 C# 驱动程序的 MongoDB 性能较慢,而不是在命令行中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26180102/