Является ли структура агрегации Mongodb быстрее, чем карта / сокращение?
Является ли структура агрегации, введенная в mongodb 2.2, имеет какие-либо особые улучшения производительности по сравнению с map / reduce?
Если да, то почему и как и сколько?
(Уже я сделал тест для себя, и производительность была почти такой же)
- Почему добавление «" в String сохраняет память?
- Зачем использовать AJAX, когда доступны WebSockets?
- Как ускорить запуск Java VM (JVM)?
- Странная ветвящаяся производительность
- Как передавать значения на страницах ASP.net без использования сеанса
- Ошибка производительности XmlSerializer при указании XmlRootAttribute
- Студия Android занимает слишком много памяти
- Нюансы NSMutableArray initWithCapacity
- Почему векторизация цикла не улучшает производительность
- Выполнение qsort vs std :: sort?
- Внедрение средства просмотра журналов с помощью WPF
- Производительность dynamic_cast?
- Эффективное вычисление линейной комбинации столбцов data.table
Каждый тест, который я лично выполнял (включая использование ваших собственных данных), показывает, что структура агрегации является кратчайшей быстрее, чем уменьшение карты, и, как правило, на порядок быстрее.
Просто взяв 1/10 данных, которые вы опубликовали (но вместо того, чтобы очищать кэш ОС, сначала нагревая кеш, потому что я хочу измерить производительность агрегации, а не то, сколько времени потребуется на странице в данных), я получил следующее:
MapReduce: 1,058 мс
Агрегационная структура: 133 мс
Удаление $ match из структуры агрегации и {query:} из mapReduce (потому что оба будут просто использовать индекс, и это не то, что мы хотим измерить) и группирование всего набора данных с помощью key2. Я получил:
MapReduce: 18,803мс
Агрегационная структура: 1535 мс
Это очень похоже на мои предыдущие эксперименты.
Мой контрольный показатель:
== Генерация данных ==
Сгенерируйте 4 миллиона строк (с python) легко с приблизительно 350 байтами. Каждый документ имеет следующие ключи:
- key1, key2 (два случайных столбца для проверки индексации, один с мощностью 2000 и один с мощностью 20)
- longdata: длинная строка для увеличения размера каждого документа
- value: простое число (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)
== Тесты ==
Я сделал несколько тестов, но одного достаточно для сравнения результатов:
ПРИМЕЧАНИЕ. Сервер перезапускается, а кеш OS очищается после каждого запроса, чтобы игнорировать эффект кэширования.
QUERY: совокупность всех строк с key1=somevalue
(около 200 тыс. key1=somevalue
) и сумма для каждого key2
- карта / уменьшить 10,6 с
- увеличить 9,7 с
- группа 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 } })