2014-07-27 18 views
7

Mam kolekcję MongoDB z ponad 1 000 000 rekordów. Każdy rekord ma rozmiar około 20 KB (więc całkowity rozmiar kolekcji wynosi około 20 GB).

Mam pole "typ" w kolekcji (może mieć około 10 różnych wartości). Chciałbym uzyskać liczniki każdego rodzaju dla kolekcji. Istnieje również indeks w polu "typ".

Przetestowałem dwa różne podejścia (zakładamy składni Pythona):

naiwny sposób - za pomocą „count” wzywa do każdej z wartości:

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

Korzystanie ramy agregacji z „$ Składnia grupy:

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

Wyniki, które otrzymuję dla pierwszego podejścia, są o 2 rzędy wielkości szybsze niż dla drugiego podejścia. Wydaje się być związane z faktem, że licznik działa tylko na indeksach, bez dostępu do dokumentów, podczas gdy $ group musi przeglądać dokumenty jeden po drugim. (To około 1 minuty vs. 45 minut).

Czy istnieje sposób na wydajne zapytanie grupujące w indeksie "typ", który wykorzystywałby tylko indeks, uzyskując w ten sposób wyniki wydajności z nr 1, ale wykorzystując strukturę agregacji?

Używam MongoDB 2.6.1

Aktualizacja: https://jira.mongodb.org/browse/SERVER-11447 jest otwarty w tej sprawie w MongoDB Jira.

+1

Dobrze dla jednej ramy agregacja nie używa indeksu, spróbuj dodać: {$ Sortuj:} zanim grupa – Sammaye

+0

dodane, nie wydaje się, aby pomóc. Jeśli instrukcja $ group nadal będzie musiała uzyskiwać dostęp do dokumentów jeden po drugim, sortowanie nie powinno mieć znaczenia ... –

+0

To nie powinno, ale optymalizacje mają sprawić, że będzie korzystał z indeksu. Wiem jednak, że agregacja framework nadal nie może korzystać z objętych indeksów, ale warto było spróbować. – Sammaye

Odpowiedz

0

w potoku agregacji klauzula $ group nie używa indeksów. Powinien być użyty po dopasowaniu $, który rzeczywiście może użyć indeksów, aby go przyspieszyć.

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

okrzyki,

+2

... niewiele pomoc, jeśli chcesz pogrupować całą kolekcję, jak mówi – Sammaye

+0

Dokładnie - dopasowanie $ nie pomaga mi tutaj ... –

+0

wydaje się, że najbardziej wydajnym sposobem jest wielokrotne zapytanie. Jeśli nie potrzebujesz danych w czasie rzeczywistym, możesz użyć warstwy pamięci podręcznej. Ale nie można przyspieszyć za pomocą struktury agregacji. – dantespot

Powiązane problemy