2014-07-27 114 views
7

我有一個超過1,000,000條記錄的MongoDB集合。 每個記錄大小約爲20K(因此總收集大小約爲20GB)。

我在集合中有一個'type'字段(可以有大約10個不同的值)。 我想獲得集合的每類型計數器。 另外,'type'字段上有一個索引。

我已經測試了兩種不同的方法(假設Python語法):

一個幼稚的方法 - 使用「計數」要求每個值:用「$

for type_val in my_db.my_colc.distinct('type'): 
    counters[type_val] = my_db.my_colc.find({'type' : type_val}).count() 

使用聚合框架組的語法:

counters = my_db.my_colc.aggregate([{'$group' : {'_id': '$type', 'agg_val': { '$sum': 1 } }}]) 

我收到的第一種方法的性能比第二種方法快大約2個數量級。 似乎與計數僅在索引上運行而不訪問文檔相關,而$ group必須逐個檢查文檔。 (大約1分鐘比45分鐘)。

有什麼辦法可以在'type'索引上運行一個高效的分組查詢,它只使用索引,從而實現#1的性能結果,但使用聚合框架?

我使用MongoDB的2.6.1

更新: https://jira.mongodb.org/browse/SERVER-11447在這個問題上MongoDB中吉拉開。

+1

那麼對於一個聚合框架不使用索引,試着加入:{$排序:類型}組 – Sammaye

+0

增加,似乎之前沒有幫助。如果$ group語句仍然需要逐一訪問這些文檔,排序應該沒有什麼區別...... –

+0

它不應該,但優化應該使它使用索引,但我知道但是聚合框架仍然不能使用覆蓋索引,但值得一試 – Sammaye

回答

0

在聚合管道中$ group子句不使用索引。它應該在$匹配後使用,它確實可以使用索引來加速它。

http://docs.mongodb.org/manual/core/aggregation-pipeline/#aggregation-pipeline-operators-and-performance

歡呼聲,

+2

...並不多幫助,如果你需要整個集合,他說 – Sammaye

+0

正確 - $匹配不幫我在這裏... –

+0

它似乎最高性能的方式是多查詢之一。如果你不需要實時數據,你可以使用緩存層。但是你不能用聚合框架加速它。 – dantespot