Производительность MongoDB по запросам агрегации - PullRequest
27 голосов
/ 08 апреля 2010

Узнав так много хорошего о производительности MongoDB, мы решили дать Mongodb попытку решить проблему, которая у нас есть. Я начал с перемещения всех записей, которые мы имеем в нескольких базах данных mysql, в одну коллекцию mongodb. Это привело к коллекции с 29 миллионами документов (у каждого из них есть по крайней мере 20 полей), которая занимает около 100 ГБ пространства в HD. Мы решили поместить их все в одну коллекцию, поскольку все документы имеют одинаковую структуру, и мы хотим запрашивать и объединять результаты по всем этим документам.

Я создал несколько индексов для соответствия моим запросам, иначе даже простое count () заняло бы целую вечность. Однако такие запросы, как Different () и group (), все еще занимают слишком много времени.

Пример:

// creation of a compound index    
db.collection.ensureIndex({'metadata.system':1, 'metadata.company':1})

// query to get all the combinations companies and systems
db.collection.group({key: { 'metadata.system':true, 'metadata.company':true }, reduce: function(obj,prev) {}, initial: {} });

Я посмотрел на журнал mongod, и в нем много таких строк (при выполнении запроса выше):

Thu Apr  8 14:40:05 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1048890 nreturned:417 154ms
Thu Apr  8 14:40:08 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1050205 nreturned:414 430ms
Thu Apr  8 14:40:18 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1049748 nreturned:201 130ms
Thu Apr  8 14:40:27 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1051925 nreturned:221 118ms
Thu Apr  8 14:40:30 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {}  bytes:1053096 nreturned:250 164ms
...
Thu Apr  8 15:04:18 query database.$cmd ntoreturn:1 command  reslen:4130 1475894ms

Этот запрос занял 1475894мс, что намного больше, чем я ожидал (список результатов содержит около 60 записей). Прежде всего, ожидается ли это, учитывая большое количество документов в моей коллекции? Ожидается ли, что запросы агрегации в целом будут такими медленными в mongodb? Любые мысли о том, как я могу улучшить производительность?

Я использую mongod на одной машине с двухъядерным процессором и 10 ГБ памяти.

Спасибо.

Ответы [ 3 ]

22 голосов
/ 10 апреля 2010

Идея состоит в том, чтобы повысить производительность запросов агрегации с помощью MapReduce в изолированной базе данных, которая распределена по нескольким компьютерам.

Я провел несколько сравнений производительности Mapreduce Монго с оператором group-by-select в Oracle на той же машине. Я обнаружил, что Монго был примерно в 25 раз медленнее. Это означает, что мне нужно распределить данные по крайней мере на 25 компьютерах, чтобы получить такую ​​же производительность с Mongo, как Oracle на одной машине. Я использовал коллекцию / таблицу с примерно 14 миллионами документов / строк.

Экспорт данных из mongo через mongoexport.exe и использование экспортированных данных в качестве внешней таблицы в Oracle и группировка в Oracle были намного быстрее, чем использование собственного MapReduce Монго.

8 голосов
/ 24 февраля 2012

Пара вещей.

1) Ваш групповой запрос обрабатывает лотов данных. Несмотря на то, что ваш набор результатов небольшой, похоже, он выполняет масштабирование таблицы всех данных в вашей коллекции, чтобы получить такой маленький результат. Это, вероятно, коренная причина медлительности. Чтобы ускорить это, вам может потребоваться посмотреть производительность диска вашего сервера через iostat во время выполнения запроса, поскольку это, вероятно, является узким местом.

2) Как указывалось в других ответах, команда group использует интерпретатор javascript, который ограничивает производительность. Вы можете попробовать использовать новую платформу агрегации, которая выпущена как бета-версия в 2.1 (примечание: это нестабильная версия по состоянию на 24 февраля 2012 года). См. http://blog.mongodb.org/post/16015854270/operations-in-the-new-aggregation-framework для хорошего введения. Это не решит проблему с объемом данных в (1), но он реализован в C ++, и, если время JavaScript является узким местом, то оно должно быть намного быстрее.

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

6 голосов
/ 13 июня 2011

Агрегация (сокращение или иное отображение) в монго очень медленная, потому что она выполняется виртуальной машиной javascript, а не ядром базы данных. Это по-прежнему является ограничением этого (очень хорошего, imo) дБ для данных временных рядов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...