使用will_paginate而不使用:total_entries可以改善冗长的查询

mwi*_*ams 5 ruby pagination ruby-on-rails will-paginate

我有一个当前的will_paginate实现,它使用paginate_by_sql方法来构建要分页的集合.我们有一个针对total_entries的自定义查询,这个查询非常复杂并且会给我们的数据库带来很大的负担.因此,我们希望完全从分页中删除total_entries.

换句话说,我们只是喜欢"下一个 - 上一个"按钮,而不是"前一个[2] 3 4 5下一个"的典型分页显示.但我们需要了解一些事情.

  1. 我们是否显示上一个链接?只有当记录存在于当前选择中显示的记录之前时,才会发生这种情况
  2. 我们是否显示下一个链接?如果正在显示集合中的最后一条记录,则不会显示此信息

来自文档

如果您不提供:total_entries,则会自动生成对行计数的查询.如果您遇到此生成的SQL的问题,您可能希望在应用程序中手动执行计数.

所以最终理想情况如下.

  • 删除total_entries计数,因为它会导致数据库负载过大
  • 使用半分页显示50个记录,仅使用下一个/上一个按钮进行导航,而不需要显示所有可用的页码
  • 仅相应显示下一个按钮和上一个按钮

有没有人处理类似的问题或对决议有什么想法?

tad*_*man 14

在很多情况下,will_paginate在计算条目数方面做得非常糟糕,特别是如果涉及的连接会使计数SQL生成器混淆.

如果您只需要一个简单的上一个/下一个方法,那么您需要做的就是尝试从数据库中检索N + 1个条目,如果您只获得N或者少于最后一页上的N + 1条目.

例如:

per_page = 10
page = 2

@entries = Thing.with_some_scope.find(:all, :limit => per_page + 1, :offset => (page - 1) * per_page)

@next_page = @entries.slice!(per_page, 1)
@prev_page = page > 1
Run Code Online (Sandbox Code Playgroud)

您可以轻松地将其封装在某些模块中,该模块可以包含在需要它的各种模型中,或者进行控制器扩展.

我发现这比默认的will_paginate方法效果要好得多.

唯一的性能问题是MySQL的限制,这可能是一个问题,具体取决于表的大小.

无论出于何种原因,在MySQL中使用小LIMIT执行查询所花费的时间与OFFSET成正比.实际上,数据库引擎会读取导致特定偏移值的所有行,然后返回下一个LIMIT数字行,而不是按照您的预期跳过.

对于大数据集,如果您的OFFSET值在100,000加上范围内,您可能会发现性能显着下降.这将表明加载页面1非常快,页面1000有点慢,但页面2000非常慢.