Search code examples
mysqlmongodbmongo-java

Why mongoDB takes less time for Select than Fetch time?


I have collection with 10mill rows without any index.In this case system should read whole table ?

When i use eplain statement then it shows db.employees.find({hundreds2:{$lt:1}},{}).explain(); "nscannedObjects" : 10000000, "n" : 105 millis" : 6027

It works fine.

But i am using java to process query . Here is code

                  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; 

But after test result .I got this information

selTime=2 fetchTime=6350 numRows105 TotalTime6352
 selTime=0 fetchTime=6290 numRows471 TotalTime6290
 selTime=0 fetchTime=6365 numRows922 TotalTime6365

Why fetch time is more than select .As per my knowledge ,while loop is just printing data . Why it taking so much time to print and how mongoDB select number of rows with 0 or 2 millSec?

Same experiment i did in MySQL with similiar code and results are

selTime=6302 fetchTime=1 numRows105 TotalTime6303
selTime=6318 fetchTime=1 numRows471 TotalTime6319
selTime=6387 fetchTime=2 numRows922 TotalTime6389


Solution

  • MongoDB uses lazy evaluation with cursors. That means in many cases when you start a MongoDB query which returns a cursor, the query doesn't get executed yet.

    The actual selection happens when you start requesting data from the cursor.

    The main reason is that this allows you to call methods like sort(by), limit(n) or skip(n) on the cursor which can often be processed much more efficiently on the database before selecting any data.

    So what you measure with the "fetch time" is actually also part of the selection.

    When you want to force the query to execute without fetching any data yet, you could call explain() on the cursor. The database can't measure the execution time without actually performing the query. However, in actual real-world use, I would recommend you to not do this and use cursors the way they were intended.