MongoDB不使用skip作分页

mysql  能够借鉴的思想mysql

MongoDB不使用skip作分页sql

使用Skip和limit能够以下作数据分页:数据库

Code: page1 = db.things.find().limit(20)
page2 = db.things.find().skip(20).limit(20)
page3 = db.things.find().skip(40).limit(20)

当数据量很小时,这样作分页彻底没有问题。可是当数据量很大时,skip操做会变的很慢,应该避免使用。(不止是mongoDb会这样,大部分数据库都是。)能够经过改变查询文档的规则来达到分页效果,避免使用skip来跳过大量的数据。(经过计算,获得下次查询应该从什么地方开始)ip

如下演示如何经过改变查询规则来避免使用skip。若是有如下数据:文档

Code: {'date':'2011-07-05 09:53:00'}
{'date':'2011-07-05 09:53:01'}
{'date':'2011-07-05 09:53:02'}
...
{'date':'2011-07-05 09:54:00'}

则数据库的第一页能够这样得到:it

Code: page1 = db.xx.find().sort('date',1).limit(10)

而后经过遍历,展现,而且得到最后一个数据:test

Code: var latest = null;

while (page1.hasNext()) {
   latest = page1.next();
   display(latest);
}

如今,经过得到的最后一个日期的数据,能够作下一个查询:date

Code: var page2 = db.xx.find({"date" : {"$gt" : latest.date}});
page2.sort({"date" : 1}).limit(10);

以次类推,能够一直得到到最后一个的分页。遍历

固然,这里展现的只是一个理想的状况,事实上,可能分页的时候,有不少值的数值都是同样的,例如:分页

Code: {'date':'2011-07-05 09:53:00'}
{'date':'2011-07-05 09:53:01'}
{'date':'2011-07-05 09:53:01'}
{'date':'2011-07-05 09:53:01'}
{'date':'2011-07-05 09:53:01'}
{'date':'2011-07-05 09:53:01'}

{'date':'2011-07-05 09:53:02'}
{'date':'2011-07-05 09:53:03'}
{'date':'2011-07-05 09:53:04'}
...
{'date':'2011-07-05 09:54:00'}

在这个例子中,若是第一个分页落在{'date':'2011-07-05 09:53:01'}附近的话,就会有5条重复的(极端状况下,可能有很是多,例如好几百条同样的键值),这样在调用{"$gt" : latest.date}时,可能会把上一页的尾数据也给包含进来了。在这种状况下,就须要使用一些别的field来辅助分页,或者转回采用skip,或者若是你的分页不是特别的严格,能够忽略这种状况。(例如mop,天涯首页那种,每页有好几百页帖子,每一秒每一页都不同。)

 

用where+limt是最快的mongo是用skip翻页,这个很是慢