2015-02-06 119 views
24

我有一個有數百萬行的mongoDB集合,我試圖優化我的查詢。我目前正在使用聚合框架來檢索數據並按照我的意願對它們進行分組。我典型的聚合查詢是這樣的:$match > $group > $ group > $project

但是,我注意到最後的部分只需要幾毫秒,開始是最慢的。

我試着只用$ match過濾器執行查詢,然後用collection.find執行相同的查詢。聚合查詢需要大約80ms,而find查詢需要0或1ms。

我在幾乎每個領域的索引,所以我想這不是問題。有什麼想法可能會出錯?或者這只是聚合框架的一個「正常」缺陷?

我可以用找到的查詢,而不是聚集查詢,但是我會請求後,進行大量的處理,這個過程能夠儘快與$group等來這樣做,我寧願保持聚合框架。

感謝,

編輯:

這裏是我的準則:

{ 
    "action" : "click", 
    "timestamp" : { 
      "$gt" : ISODate("2015-01-01T00:00:00Z"), 
      "$lt" : ISODate("2015-02-011T00:00:00Z") 
    }, 
    "itemId" : "5" 
} 
+0

你可以發佈你的'$匹配'並找到?在大多數用法中,'$ match'和find應該是等價的,但我想確切地看到您正在比較哪些語句以便做出準確的答案。此外,你是否先運行聚合,然後查找?如果你反覆重複兩遍並比較時間,會發生什麼?差異可能是將結果從磁盤移動到內存中的成本。 – wdberkeley 2015-02-06 16:07:34

+0

我在第一篇文章中添加了標準,但是即使沒有時間戳標準,我也看到了很大的差距。但是現在我想知道它是否與find()返回一個遊標並僅顯示第一個結果有關。 – Owumaro 2015-02-06 16:13:41

+7

好吧,我有很多無用的索引,所以我清理了一切,並創建了一個複合索引(與我的$匹配過濾器的字段)。現在我有良好的表現和相同的表現,尋找和聚合$匹配:)問題解決了。 – Owumaro 2015-02-09 13:04:31

回答

14

aggregation framework的主要目的是緩解一個大數量的條目的查詢並生成一個低數對你有價值的結果。如您所說,您也可以使用多個find查詢,但請記住,您不能使用find查詢創建新字段。另一方面,$group階段允許您定義新的字段。

如果你想實現aggregation framework的功能,你很可能必須運行一個初始的find(或連鎖幾個),拉動這些信息並用編程語言進一步處理它。

aggregation pipeline似乎需要更長的時間,但至少你知道你只需要考慮到一個系統的性能 - MongoDB引擎。

鑑於,當涉及操縱從find查詢返回的數據時,您很可能必須用編程語言進一步操作數據,從而增加了複雜性,具體取決於選擇的編程語言的複雜性。

+9

感謝您的信息。不過,我仍然不明白爲什麼只有$ match過濾器的聚合查詢不如使用相同過濾器的簡單find查詢快。 – Owumaro 2015-02-06 12:56:01

3

您是否嘗試過使用explain()來查找查詢?它會給你一個很好的想法,find()查詢會花費多少時間。您可以使用$ explain &進行$匹配,查看索引訪問&其他參數是否有任何區別。

此外,聚合框架的$ group部分不使用索引,因此它必須處理聚合框架的$ match階段返回的所有記錄。因此,爲了更好地理解查詢的工作情況,請參閱結果集,它返回&是否適合要由MongoDB處理的內存。