2012-03-13 36 views
2

從2012年3月13日起,我安裝了最新的MongoDB 64位數據庫和官方C#驅動程序。我使用遊標獲得了一些意想不到的性能結果。MongoDB C#光標性能問題

以下約26.8 K /秒的代碼將檢索和環通500000條記錄在我的Core 2 Duo 2 GHz的筆記本電腦:

var query = Query.EQ("_H._t", "Car"); 
    var cursor = mc.FindAs<RoctObj>(query); 
    double priceTot = 0d; 

    foreach (RoctObj item in cursor) 
    { 
     Car car = (Car)item._H; 
     priceTot += car.Price; 
    } 

這似乎是合理的。接下來,我調整了查詢​​,以便只返回721個結果。代碼接管1.1秒長於執行如果在foreach段被替換爲:

long i = cursor.Count(); 

鑑於第一實施例的速度,721個記錄應該只需要幾分之一秒進行迭代。我知道還有一些其他的開銷,但他們應該那麼糟糕。我不明白爲什麼我要+1.1秒。

任何想法?

EDIT

下面是備用的查詢。請注意,查詢時間不是問題。這是迭代時間。

var query = Query.And(
     Query.LTE("_H.Price", BsonDouble.Create(80000d)).GTE(BsonDouble.Create(40000d)), 
     Query.LTE("_H.Cylinders", BsonDouble.Create(8d)).GTE(BsonDouble.Create(4d)), 
     Query.LTE("_H.Capacity", BsonDouble.Create(3000d)).GTE(BsonDouble.Create(2000d)), 
     Query.LTE("_H.TopSpeed", BsonDouble.Create(200d)).GTE(BsonDouble.Create(100d)) 
     ); 
+0

您是如何調整查詢的?你剛剛使用了「限制」嗎?您應該使用'explain()'功能來更好地瞭解這兩個查詢計劃,並且可以將其添加到您的問題中。 – 2012-03-13 19:36:22

+0

我在編輯中顯示了調整後的查詢。雖然查詢的執行時間不是問題,但我該如何使用C#中的解釋? – IamIC 2012-03-13 19:39:42

+0

而不是使用C#驅動程序進行解釋,請使用shell或更好的GUI,比如MongoVUE,這非常棒。你確定它不是查詢時間的問題嗎?你怎麼確定? MongoDB不會一次返回所有結果,它會返回一個遊標,它會一次一個記錄地從數據庫中讀取數據,就像應用程序要求的那樣(即在迭代過程中) – 2012-03-13 19:42:42

回答

1

的MongoDB不立即返回所有的結果,(在你的迭代IE)返回遊標這一次讀取關閉數據庫中的一個記錄數據,您的應用程序需要它這可能是爲什麼速度較慢。

運行count()只是返回找到但沒有數據的匹配數量。

3

調用cursor.Count()不會將數據從服務器傳輸到您的應用程序。它向服務器發送一個命令,並在服務器上執行計數,並且只有一個小數據包從服務器返回,其中包含計數的數字結果。

不確定爲什麼遍歷文檔需要比簡單計數長得多的時間。其中一個原因可能是服務器只能使用索引來計算計數,但是如果實際遍歷文檔,服務器必須從磁盤讀取每個文檔(如果尚未將其分頁到內存中)。

這不可能是C#驅動程序反序列化代碼中的瓶頸,因爲這非常快。

如果您可以提供演示觀察行爲的示例程序,我會很樂意嘗試並重現您的結果。

+0

我運行了相同的測試,但數據庫大小爲10%,結果快了30倍,這確認了MDB必須去磁盤 – IamIC 2012-03-14 06:26:12

+0

感謝@羅伯特最後,我已經總結了你在這裏說的同樣的東西雖然Mongo知道有700多條記錄因爲索引,因此可以給我答案,它還沒有經過它們,它們是分散的,然而,500,000實際上是每一秒的記錄,這意味着它有50%的有效順序讀取。 – IamIC 2012-03-14 06:28:23