Почему mongoDB требует меньше времени для выбора, чем время выборки?
У меня есть коллекция с 10-миллионными строками без индекса. В этом случае система должна читать всю таблицу?
Когда я использую оператор eplain, он показывает db.employees.find({сотни2:{$lt:1}},{}). Объяснение (); "nscannedObjects": 10000000, "n": 105 миллис ": 6027
Работает нормально.
Но я использую Java для обработки запроса. Вот код
whereQuery = new BasicDBObject();
whereQuery.put("hundreds2",new BasicDBObject("$lt", rangeQuery));
timer.start();
setupMongoDBReadQuery(arrForRange[posOfArr]);
cursor = coll.find(whereQuery);
timer.stop();
this.selectTime= timer.elapsed();
timer.start();
while (cursor.hasNext())
{
numberOfRows++;
cursor.next();
}
timer.stop();
this.fetchTime= timer.elapsed();
this.totalOfSelAndFetch=this.selectTime+this.fetchTime;
Но после результата теста. Я получил эту информацию
selTime=2 fetchTime=6350 numRows105 TotalTime6352
selTime=0 fetchTime=6290 numRows471 TotalTime6290
selTime=0 fetchTime=6365 numRows922 TotalTime6365
Почему время выборки больше, чем выбор. Насколько мне известно, в то время как цикл просто печать данных. Почему печать занимает так много времени и как mongoDB выбирает количество строк с 0 или 2 millSec?
Тот же эксперимент, который я сделал в MySQL с похожим кодом и результаты
selTime = 6302 fetchTime = 1 numRows105 TotalTime6303
selTime = 6318 fetchTime = 1 numRows471 TotalTime6319
selTime = 6387 fetchTime = 2 numRows922 TotalTime6389
1 ответ
MongoDB использует ленивые вычисления с курсорами. Это означает, что во многих случаях, когда вы запускаете запрос MongoDB, который возвращает курсор, запрос еще не выполняется.
Фактический выбор происходит, когда вы начинаете запрашивать данные у курсора.
Основная причина в том, что это позволяет вам вызывать такие методы, как sort(by)
, limit(n)
или же skip(n)
на курсоре, который часто может быть гораздо более эффективно обработан в базе данных, прежде чем выбирать какие-либо данные.
То, что вы измеряете с помощью "времени выборки", на самом деле также является частью выбора.
Если вы хотите, чтобы запрос выполнялся без извлечения каких-либо данных, вы можете вызвать explain()
на курсоре. База данных не может измерить время выполнения без фактического выполнения запроса. Однако при реальном использовании я бы порекомендовал вам не делать этого и использовать курсоры так, как они предназначались.