簡體   English   中英

使用C#驅動程序的MongoDB性能較慢,而不是在命令行中

[英]MongoDB performance slow with C# driver, not in commandline

我正在探索MongoDB以檢查我們是否可以/將它用作我們產品的noSQL存儲。 一切似乎都運行良好,但在我們的C#應用​​程序中它相當慢。 查詢大約需要120到140毫秒才能返回結果,這對我們的應用程序來說是不可接受的(比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控制台中運行此查詢時,它返回0ms的結果(根據解釋)

> 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集合中添加了一些更多的數據,以查看返回很多(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 } 

如您所見,返回大約100.000個結果的時間是53毫秒

通過MongoDB驅動程序運行FindAll().ToList()方法導致在5075毫秒內接收所有文檔。 相當不同!

關於我正在運行它的機器的更多背景信息:我在西歐地區設置了2台Azure Standard_A2機器(2核,3.5GB內存)。

其中一台機器正在運行MongoDB數據庫。 我在C:\\MongoDBC:\\MongoDB\\bin\\data上的數據目錄中安裝了它。 這僅用於測試目的。 當然,沒有真正的生產系統可以在這個驅動器上安裝日期。

測試數據庫大小約為135MB。

在另一台機器上,我安裝了測試客戶端,控制台應用程序使用MongoDB C#驅動程序和MongoDB.exe。 兩者都通過相同的HTTP端點連接到數據庫。

EDIT3

我剛剛運行了沒有<T>QueryTest方法,所以現在我將返回' BsonDocument 奇怪的是,它甚至更慢。 100.000文件現在需要大約8000毫秒返回,而返回POCO他們返回大約5000毫秒。

在shell中進行比較時遇到的問題是shell在運行.explain()時實際上並沒有回退任何數據。 實際上,您已經消除了整個網絡堆棧。 因此,您看到的53毫秒是服務器迭代所有數據所需的時間。 由於您在Azure中運行,我非常確定網絡將占用大部分開銷。 您可以通過同時運行網絡捕獲來證明這一點,並查看TCP請求需要多長時間。

此外,當查詢這么多結果時,MongoDB會批量發送結果。 這意味着它不僅僅是一次網絡往返。 相反,它們中的一些,每個都增加了時間的開銷。

我在1411ms檢索了100,000條記錄,問題應該是其他問題,例如硬故障或......如果你想在foreach循環中使用它,你可以避免'.ToList()'代碼使用結果作為MongoCursor

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM