【发布时间】:2016-06-28 10:15:09
【问题描述】:
我在使用 MongoDB C# 驱动程序时遇到了非常奇怪的问题。我有一个非常简单的查询,并且我对该查询有一个正确的索引。当我使用 MongoChef(并使用 shell)运行查询时,我会在 22 毫秒内得到结果 但是当我的应用程序运行相同的查询时,它需要大约 2.5 分钟才能返回答案(这不是由于网络问题)。
我已经检查了 db.currentOp() 并且我看到该操作确实需要大约 2.5 分钟才能完成,并且查询与我手动运行的查询相同,并且执行计划确实使用了索引。 任何想法? 谢谢
附言 问题不在于结果集的大小!我已经测试了具有 0 个结果、21 个结果和 600,000 个结果的结果集,所有这些结果都非常糟糕! (2m 以上只有 21 个结果,在 shell 中不需要时间!)
{
"inprog": [
{
"opid" : 53214,
"active" : true,
"secs_running" : 174,
"microsecs_running" : 174085497,
"op" : query,
"ns" : db.collection,
"query" : {{$query : {ParentId: 55, IsDeleted : false}},
{$orderby : {_id : -1}}},
"planSummary": IXSCAN {_id : 1},
"client" : ip:port,
"desc" : conn121254,
"threadId" : 0x1234567,
"connectionId" : 1254651,
"locks" : {
"Global" : r,
"MMAPV1Journal" : r,
"Database" : r,
"Collection" : R
},
"waitingForLock" : false,
"numYields" : 46963,
"lockStats" : {
"Global" : {acquireCount : { r : 93928}},
"MMAPV1Journal" : {acquireCount : { r : 46964} , acquireWaitCount : { r : 2 }, timeAcquiringMicros: { r : 2 } },
"Database" : {acquireCount : { r : 46964}},
"Collection" : {acquireCount : { r : 46964}}
}
}
]
}
在 shell 上运行良好的查询(22 毫秒)
db.collection.find({ParentId : 55, IsDeleted : false}).sort({_id : 1})
C# 代码示例:
MongoClient client = new MongoClient("mongodb://MongosServer01:27017,MongosServer02:27017,MongosServer03:27017,MongosServer04:27017");
var collection = client.GetServer().GetDatabase("db").GetCollection<BsonDocument>("collection");
var cursor = collection.Find(Query.And(Query.EQ("ParentId" , 55),Query.EQ("IsDeleted" , false))).SetSortOrder("_id").SetLimit(20);
【问题讨论】:
-
您能否发布查询的 C# 和 shell 代码以及解释?如果您的结果集很大,一个可能的区别是
mongoshell 默认只迭代前 20 个结果,而您的应用程序代码可能会迭代整个结果集。 -
我不能真正发布我的代码,我会尽快发布我的解释。看我给出的进一步解释,你就会明白为什么我不认为它与结果集或任何迭代有关(TL;DR:我在非常小的结果集上尝试过)
-
除非您不发布您的 C# 代码,否则很难查明问题或做出任何判断。
-
添加了处理这个查询的部分代码,没什么特别的
-
我现在对 Java 也有同样的问题。我从 mongodb logs 中看到一个慢查询日志,耗时 15 秒。我只是将它复制粘贴到 shell 中,它会立即运行。然后我再次尝试使用 Java 进行相同的查询,再次需要 15 秒......我没有想法。 (java app和shell都是在同一台机器上运行的,和网络无关)
标签: c# mongodb query-optimization database