我在通過C#使用MongoDB聚合框架時遇到了性能問題。在C#中執行時,通過Mongo Shell快速運行的聚合需要永久性。通過C#使用MongoDB聚合框架時的性能問題
試圖調用通過C#的框架之前,我通過蒙戈shell中執行下列聚合檢查一切正常:
db.runCommand(
{
aggregate: "actions",
pipeline :
[
{ $match : { CustomerAppId : "f5357224-b1a8-4f1a-8ea2-a06a00ca597a", ActionName : "install"}},
{ $group : { _id : { CustomerAppId:"$CustomerAppId",ActionDate:"$ActionDate" }, count : { $sum : 1 } }}
]
});
在< 500ms的執行的腳本和返回預期的大約200個結果( CustomerAppId被定義爲數據庫中的一個字符串,不可能在集合框架中使用GUID)。
然後,我移植了相同的腳本到C#:
var pipeline = new BsonArray
{
new BsonDocument
{
{
"$match",
new BsonDocument
{
{"CustomerAppId", "f5357224-b1a8-4f1a-8ea2-a06a00ca597a"},
{"ActionName", "install"}
}
},
{ "$group",
new BsonDocument
{
{ "_id", new BsonDocument
{
{
"CustomerAppId","$CustomerAppId"
},
{
"ActionName","$ActionName"
}
}
},
{
"Count", new BsonDocument
{
{
"$sum", 1
}
}
}
}
}
}
};
var command = new CommandDocument
{
{ "aggregate", "actions" },
{ "pipeline", pipeline }
};
(請讓我知道是否有寫在C#中聚集:)更簡單的方法)
我敢執行像這樣的:
var result = db.RunCommand(command);
的問題是,它殺死服務器:該CPU和內存使用走一路上揚。當我檢查db.currentOp(),我可以看到聚集的操作,但我最終還是把它用db.killOp(1281546)殺:
"opid" : 1281546,
"active" : true,
"secs_running" : 294,
"op" : "query",
"ns" : "database.actions",
"query" : {
"aggregate" : "actions",
"pipeline" : [
{
"$match" : {
"CustomerAppId" : "f5357224-b1a8-4f1a-8ea2-a06a00ca597a",
"ActionName" : "install"
},
"$group" : {
"_id" : {
"CustomerAppId" : "$CustomerAppId",
"ActionName" : "$ActionName"
},
"Count" : {
"$sum" : 1
}
}
}
]
},
對我而言,操作看起來完全罰款和類似腳本我直接從mongo shell運行。感覺像通過C#運行聚合會導致MongoDB錯過索引,並且它正在對集合中所有大約600萬個文檔執行表掃描。
任何想法?
更新:日誌
得益於Cirrus的建議,我啓用了詳細日誌記錄,然後用尾巴來獲取查詢。和他們是不同的!所以我認爲我的C#端口有問題。有關如何正確格式化查詢的任何想法?
當通過外殼執行查詢:
Mon Oct 8 15:00:13 [conn1] run command database.$cmd { aggregate: "actions", pipeline: [ { $match: { CustomerAppId: "f5357224-b1a8-4f1a-8ea2-a06a00ca597a", ActionName: "install" } }, { $group: { _id: { CustomerAppId: "$CustomerAppId", ActionDate: "$ActionDate" }, count: { $sum: 1.0 } } } ] }
Mon Oct 8 15:00:13 [conn1] command database.$cmd command: { aggregate: "actions", pipeline: [ { $match: { CustomerAppId: "f5357224-b1a8-4f1a-8ea2-a06a00ca597a", ActionName: "install" } }, { $group: { _id: { CustomerAppId: "$CustomerAppId", ActionDate: "$ActionDate" }, count: { $sum: 1.0 } } } ] } ntoreturn:1 keyUpdates:0 locks(micros) r:27944 reslen:12705 29ms
當通過C#執行查詢:
Mon Oct 8 15:00:16 [conn8] run command database.$cmd { aggregate: "actions", pipeline: [ { $match: { CustomerAppId: "f5357224-b1a8-4f1a-8ea2-a06a00ca597a", ActionName: "install" }, $group: { _id: { CustomerAppId: "$CustomerAppId", ActionDate: "$ActionDate" }, Count: { $sum: 1 } } } ] }
下聯丟失,我想因爲查詢未完成。
這裏再次提供日誌以方便比較。腳本到了,C#down:
Mon Oct 8 15:00:13 [conn1] run command database.$cmd { aggregate: "actions", pipeline: [ { $match: { CustomerAppId: "f5357224-b1a8-4f1a-8ea2-a06a00ca597a", ActionName: "install" } }, { $group: { _id: { CustomerAppId: "$CustomerAppId", ActionDate: "$ActionDate" }, count: { $sum: 1.0 } } } ] }
Mon Oct 8 15:00:16 [conn8] run command database.$cmd { aggregate: "actions", pipeline: [ { $match: { CustomerAppId: "f5357224-b1a8-4f1a-8ea2-a06a00ca597a", ActionName: "install" }, $group: { _id: { CustomerAppId: "$CustomerAppId", ActionDate: "$ActionDate" }, Count: { $sum: 1 } } } ] }
你知道你已經使用ActionDate在C#版C#LINQ提供MongoDB的聚合框架,而不是到Action版本的shell版本吧?除此之外,在配置文件中使用「verbose = true」開啓日誌記錄,並使用tail.exe日誌文件。它會顯示它在數據庫上執行的實際查詢。 – cirrus
其實不行!我發誓我三重檢查了一些事情,但我仍然設法想念它。但不幸的是執行速度仍然很慢。該索引包含ActionName,CustomerAppId和ActionDate。使用AppId&Date或AppId&ActionName從shell進行分組速度很快,但從代碼來看,它們都很慢。感謝提供詳細的建議。我得檢查一下。 –
不要忘記你可以upvote有用的意見,以及答案; – cirrus