如果我使用will_paginate gem做mongo查询仍然选择所有行THEN paginate?

时间:2012-02-11 20:57:23

标签: ruby-on-rails mongodb

代码:

Channel.all.paginate(:page => 3, :per_page => 25)

假设我有一张包含400,000条记录的表,上面的代码是否选择了所有400,000条记录,然后得到我需要的当前25条记录,或者仅查询我需要的25条记录。

如果查询所有400,000条记录,是否有更优化的方法来使用rails对大型数据集进行分页?

1 个答案:

答案 0 :(得分:3)

Mongo Mapper(我假设您使用的是因为查询的语法)是使用limit和skip表达式实现的。

基本上它会运行一个查询,它会跳过多个频道,然后检索限制指定的数量(每页获得的数量)。

例如:如果您在第3页并且每页有25个,则mongo mapper运行的查询如下所示:

db.channels.find().skip((page - 1) * per_page).limit(per_page)

转换为:

db.channels.find().skip(2 * 25).limit(25)

要返回结果,mongo必须跳过(page - 1) * per_page个结果,如果页码很高,这些结果可能会很昂贵。让我们说表达式的计算结果为1000,然后它必须运行查询,跳过1000多个文档并获得接下来的25个文档(限制)。 MongoDB基本上会对这些文档进行表扫描。

为避免您可以进行基于范围的分页,这样可以更好地使用索引,但不允许您轻松跳转到特定页面。

如果Channel模型有一个日期字段,例如,基于范围的分页将使用$ gte和limit而不是使用skip。您可以在x页面上获取最后一个文档的日期,并通过查询上一页最后文档的日期$ gte的文档来获取下一页的结果。如果你这样做,你可能会得到欺骗,所以使用不同的标准可能是有意义的。

在实践中,除非页面数量非常多,否则不要担心。

干杯,祝你好运!