В настоящее время мы исследуем MongoDB как возможное решение для высокораспределенной базы данных научных данных.Учитывая наши требования к запросам, мы выбрали одну коллекцию, состоящую из документов, каждый документ представляет объект и его свойства, число которых ~ 450.Типичный документ должен быть структурирован следующим образом:
d = {'patch': '12345-1,1',
'X': { (120 key-value pairs) },
'A': { (64 key-value pairs) },
...
(4 more such embedded documents)
}
В X есть целочисленный флаг.Флаг представляет собой 32-битное целое число, каждый бит представляет логический флаг.Это распространенный метод хранения логических флагов, когда их число довольно велико.Существует таблица поиска, которая показывает, какая позиция соответствует какому логическому свойству.Существует 15-й бит, который имеет отношение к нашему конкретному набору запросов.Общее количество документов составляет 600 000, которые хранятся на 3 рабочих столах (8 ГБ ОЗУ и процессор i7, стандартные вращающиеся жесткие диски со скоростью 5400 об / мин).
Запрашиваемый запрос прост - нам нужно подсчет всех документов, для которых15-й бит определенного целого флага установлен в 1.
db.coll.find(
{'X.flag1': {$bitsAllSet: [14]}}
).count()
Среднее время, затраченное на этот запрос, составляет 19 783 мс.Это не приемлемое время для нас.Мы попытались улучшить это с помощью агрегации вместо стандартного запроса find ().
db.coll.aggregate([
'$match': {
'X.flag1': {$bitsAllSet: [14]}
},
'$group': {
_id: 0,
count: {$sum: 1}
}
])
Это занимает около 10000 мс.Хотя это улучшение (которое, я думаю, связано с высокоэффективной реализацией структуры агрегации на C ++), оно все еще выходит за рамки желаемой производительности.Следующим шагом было выделить флаг, скрытый в 15-м бите, и сделать его отдельным ключом в документе.Это приведет к тем же запросам, что и выше, но вместо использования $bitsAllSet: [14]
мы будем использовать X.is_primary: 1
.Для find () и aggregate () соответствующие времена составляли 19000 мс и 8500 мс соответственно.Улучшение очень незначительное.
Итак, два моих вопроса, с которыми, я надеюсь, люди могут помочь, это:
- Является ли это последним результатом, который я могу ожидать от MongoDB Community Edition?Я знаю, что есть Enterprise Edition, который будет идти с In-Memory Engine.Но мой вопрос более специфичен для Community Edition.Есть ли какой-нибудь прием, который я мог бы использовать для ускорения запроса?
- Я постепенно нахожу, что по крайней мере для сложной серверной аналитики и запросов, которые нам нужны, MongoDB оказывается трудным для использования обоих с точки зрениясложность запросов, которые мы пишем, а также узкие места производительности.Любые советы о том, какие другие базы данных я могу рассмотреть.
Редактировать: Как и предполагалось, я делюсь выводом .explain ().Вывод для коллекции, где is_primary
не проиндексировано.Но, как обсуждалось в разделе комментариев, для логического значения наличие индекса не должно влиять на производительность запроса на основе логических флагов.
Pastebin Link (срок действия 2 недели)