Подтвердить что ты не робот

Является ли структура агрегации Mongodb быстрее, чем карта/сокращение?

Является ли структура агрегации, введенная в mongodb 2.2, имеет какие-либо особые улучшения производительности по сравнению с map/reduce?

Если да, то почему и как и сколько?

(Уже я сделал тест для себя, и производительность была почти такой же)

4b9b3361

Ответ 1

Каждый тест, который я лично выполнял (включая использование ваших собственных данных), показывает, что структура агрегации является кратчайшей быстрее, чем сокращение карты, и, как правило, на порядок быстрее.

Просто принимая 1/10 данных, которые вы опубликовали (но вместо того, чтобы очищать кэш ОС, сначала нагревая кеш), потому что я хочу измерить производительность агрегации, а не как долго это нужно для страницы в данных), я получил это:

MapReduce: 1,058ms
Агрегационная структура: 133ms

Удаление $соответствия из структуры агрегации и {query:} из mapReduce (потому что оба будут просто использовать индекс, а не то, что мы хотим измерить) и группировать весь набор данных с помощью key2. Я получил:

MapReduce: 18,803ms
Агрегационная структура: 1,535 млн. Долл. США

Это очень похоже на мои предыдущие эксперименты.

Ответ 2

Мой ориентир:

== Генерация данных ==

Сгенерируйте 4 миллиона строк (с python) легко с примерно 350 байтами. Каждый документ имеет следующие ключи:

  • key1, key2 (два случайных столбца для проверки индексации, один с мощностью 2000 и один с мощностью 20)
  • longdata: длинная строка для увеличения размера каждого документа
  • значение: простое число (const 10) для проверки агрегации


db = Connection('127.0.0.1').test # mongo connection
random.seed(1)
for _ in range(2):
    key1s = [hexlify(os.urandom(10)).decode('ascii') for _ in range(10)]
    key2s = [hexlify(os.urandom(10)).decode('ascii') for _ in range(1000)]
    baddata = 'some long date ' + '*' * 300
    for i in range(2000):
        data_list = [{
                'key1': random.choice(key1s),
                'key2': random.choice(key2s),
                'baddata': baddata,
                'value': 10,
                } for _ in range(1000)]
        for data in data_list:
            db.testtable.save(data)
Общий размер данных составил около 6 ГБ в монго. (и 2 ГБ в postgres)

== Тесты ==

Я сделал несколько тестов, но одного достаточно для сравнения результатов:

ПРИМЕЧАНИЕ. Сервер перезапускается, а кэш ОС очищается после каждого запроса, чтобы игнорировать эффект кэширования.

QUERY: совокупность всех строк с key1=somevalue (около 200 тыс. строк) и сумма value для каждого key2

  • карта/уменьшить 10.6 сек
  • aggreate 9.7 sec
  • группа 10,3 с

запросы:

карта/уменьшить:

db.testtable.mapReduce(function(){emit(this.key2, this.value);}, function(key, values){var i =0; values.forEach(function(v){i+=v;}); return i; } , {out:{inline: 1}, query: {key1: '663969462d2ec0a5fc34'} })

агрегатный:

db.testtable.aggregate({ $match: {key1: '663969462d2ec0a5fc34'}}, {$group: {_id: '$key2', pop: {$sum: '$value'}} })

группа:

db.testtable.group({key: {key2:1}, cond: {key1: '663969462d2ec0a5fc34'}, reduce: function(obj,prev) { prev.csum += obj.value; }, initial: { csum: 0 } })

Ответ 3

Как вы можете видеть в в этом блоге, совокупность примерно в 6 раз быстрее, чем уменьшение карты.