Низкая производительность при просмотре всех документов из mongodb с использованием Java.

Я храню системный журнал в mongodb с индексом построения в соответствии с полем «время». Сейчас в mongodb около 190 тысяч логов. Когда я пытаюсь получить все журналы с помощью метода DBCollection.find() в Java, он тратит почти 10 секунд на просмотр всех документов в коллекции. Я думаю, что может быть что-то, что я пропустил, что привело к плохой работе?

Вот код, который я использовал:

mongo = new Mongo();
DB db = mongo.getDB("Log");
DBCollection coll = db.getCollection("SystemLog");
int count = 0;

long findStart = Calendar.getInstance().getTimeInMillis();

// Sort by time.
BasicDBObject queryObj = new BasicDBObject();
queryObj.put("time", -1);

DBCursor cursor = coll.find().sort(queryObj);
while(cursor.hasNext()) {
    DBObject obj = cursor.next();
    // Do something
    ++count;
}
long findEnd = Calendar.getInstance().getTimeInMillis();
System.out.println("Time for traversing all system logs (" + count + "):\t" + (findEnd-findStart) + "ms.");

И напечатанный результат:

Time for traversing all system log (194309):    10496ms.

Я пробовал это несколько раз. Кажется, нет никакой разницы между запуском один раз или несколько раз. Хотя я также пытался удалить sort() и просто найти все журналы из mongodb. Для просмотра всех документов требуется около 6 секунд. Время все еще как бы неприемлемо для моего требования. Есть ли какие-нибудь советы по реализации, которые могут ускорить работу по обходу?

Большое спасибо.


person user1802604    schedule 06.11.2012    source источник


Ответы (1)


Вам действительно нужно просмотреть все документы? В приведенном выше коде кажется, что вы просто загружаете в память каждый объект один за другим.

  1. Индекс в поле «время» должен быть построен как «по убыванию», так как вы сортируете так.
  2. Если индекс составной (имеет больше полей в индексе, а не только «время»), убедитесь, что вы также добавили индекс только с «временем». Кроме того, когда вы добавите фильтр к этому запросу, убедитесь, что поле «время» добавлено последним в индексе и расположено по убыванию.
  3. Производительность не так уж и плоха, учитывая, что вы читаете 190 тыс. объектов один за другим.

(обратите внимание, что мой опыт работы с mongodb не связан с работой с драйвером Java)

person VladT    schedule 06.11.2012
comment
Спасибо за ваш ответ и предложения. Да, мне нужно просмотреть все документы. На самом деле мне нужно экспортировать все журналы из mongodb в файл, и, таким образом, я должен получать документы один за другим в память (и записывать их в текстовый файл с фиксированным форматом). Однако я надеюсь, что эта работа может быть выполнена не более чем за 5 секунд, поскольку после создания файла журнала пользователям приходится ждать еще несколько секунд для загрузки файла журнала. - person user1802604; 07.11.2012
comment
Убедитесь, что индекс времени по убыванию присутствует. Кроме того, я бы попытался получить несколько объектов одновременно. Имейте ограничение и пропускайте запрос (драйвер Java должен передать это) и получайте объекты кусками. Посмотрите в профилировщике монго, чтобы увидеть, что там происходит. В лучшем случае вы увидите курсор, который каждый раз возвращает большие куски объектов в полной индексации. - person VladT; 07.11.2012