получить большое количество записей с MongoDB в разумные сроки - PullRequest
4 голосов
/ 16 ноября 2011

Я использую mongoDB для хранения журнала запросов и получения статистики об этом.Объекты, которые я храню в mongoDB, содержат текст запроса, дату, пользователя, если пользователь щелкнул некоторые результаты и т. Д. И т. Д.

Теперь я пытаюсь получить все запросы, на которые пользователь не нажалв определенный день с Java.Мой код примерно такой:

    DBObject query = new BasicDBObject();
    BasicDBObject keys = new BasicDBObject();
    keys.put("Query", 1);
    query.put("Date", new BasicDBObject("$gte", beginning.getTime()).append("$lte", end.getTime()));
    query.put("IsClick", false);
    ...
    DBCursor cur = mongoCollection.find(query, keys).batchSize(5000);

Вывод запроса содержит около 20 тыс. Записей, которые мне нужно повторить.Проблема состоит в том, что это занимает минуты :(. Я не думаю, что это нормально. Из журнала сервера я вижу:

Wed Nov 16 16:28:40 query db.QueryLogRecordImpl ntoreturn:5000 reslen:252403 nscanned:59260 { Date: { $gte: 1283292000000, $lte: 1283378399999 }, IsClick: false }  nreturned:5000 2055ms
Wed Nov 16 16:28:40 getmore db.QueryLogRecordImpl cid:4312057226672898459 ntoreturn:5000 query: { Date: { $gte: 1283292000000, $lte: 1283378399999 }, IsClick: false }  bytes:232421 nreturned:5000 170ms
Wed Nov 16 16:30:27 getmore db.QueryLogRecordImpl cid:4312057226672898459 ntoreturn:5000 query: { Date: { $gte: 1283292000000, $lte: 1283378399999 }, IsClick: false }  bytes:128015 nreturned:2661 --> 106059ms

Таким образом, получение первого блока занимает 2 секунды,секунды 0,1 секунды, третьи 106 секунд !!! странно .. Я пытался изменить размер пакета, создать индексы для Date и IsClick, перезагрузить компьютер: P, но никак. Где я ошибаюсь?

1 Ответ

5 голосов
/ 16 ноября 2011

Здесь есть несколько факторов, которые могут влиять на скорость.Здесь необходимо собрать дополнительные данные, чтобы определить причину.

Некоторые потенциальные проблемы:

  1. Индексы: используете ли вы правильные индексы?Вы, вероятно, должны индексировать IsClick/Date.Это ставит диапазон на второе место, что является нормальным предложением.Обратите внимание, что это отличается от индексации на Date/IsClick, порядок важен.Попробуйте .explain() в своем запросе, чтобы увидеть, какие индексы используются.
  2. Размер данных: В некоторых случаях медлительность может быть вызвана слишком большим объемом данных.Это может быть слишком много документов или слишком много больших документов.Это также может быть вызвано попыткой найти слишком много игл в действительно большом стоге сена.Вы возвращаете 252 тыс. Данных (reslen) и 12 тыс. Документов, поэтому проблема, вероятно, не в этом.виртуальная память.Если у вас больше данных, чем ОЗУ, то выборка определенных документов требует «перехода на диск».Переход на диск может быть очень дорогой операцией.Вы можете идентифицировать «переход на диск», используя такие инструменты, как iostat или resmon (Windows) для мониторинга активности диска.

Исходя из личного опыта, я сильно подозреваю, что № 3 свозможное обострение от # 1.Я бы начал с просмотра ввода-вывода во время выполнения запроса .explain().Это должно быстро сузить круг возможных проблем.

...