Как оптимизировать монго-запрос для большой коллекции около 30M? - PullRequest
0 голосов
/ 23 мая 2018

В моем приложении мы регистрируем активность пользователей в коллекции аналитики сеансов, до сегодняшнего дня в нашей коллекции было около 30 миллионов записей, в основном 20 миллионов, созданных с февраля 2018 года по май 2018 года. Когда мы считаем активного пользователя в данный период времени, т.е. январьС 1 2018 по 20 мая 2018 г. Ошибка возврата тайм-аута сервера, поскольку запрос выполняется в течение 60+ секунд.Наше приложение сделано в Rails, и мой запрос

> `SessionAnalytic.collection.aggregate([
{
  "$match" => {
    "start_date" => {
      "$gte" => options[:start_date],
      "$lte" => options[:end_date]
    },
    "community_uuid" => options[:community_uuid],
    "user_type"      => options[:user_type]
  }
},
{"$group": {"_id": "$user_uuid" } },
{"$count": 'total_users' }
]).first`

Есть индексация по полям community_uuid, user_type и start_date.Любой может подсказать, почему для исполнения требуется огромное количество времени.Насколько я знаю, MongoDB может обрабатывать большие объемы данных.

1 Ответ

0 голосов
/ 23 мая 2018

Я не эксперт MongoDB, но я знаю, как работают индексы SQL, и он должен быть очень похожим.

На мой взгляд, 30M - это большое количество записей, но Mongo должен с этим справиться - но опять же, это зависит,Самый важный вопрос: есть ли у вас один индекс, который содержит 3 поля или 3 отдельных индекса?- у вас должен быть один индекс с 3 полями (или даже 4).Также этот индекс должен содержать поле $ user_uuid.Зачем?Поскольку он используется в выражении group by, поэтому, если $ user_uuid не проиндексирован, то после совпадения MongoDB необходимо извлечь $ user_uuid из исходной коллекции для каждой записи - и это будет медленно.

Если это все еще не произойдетзатем я напишу код, который объединит все действия для всех пользователей за один день и изменит ваш запрос, чтобы использовать предварительно сгруппированные данные.

...