ruby on Rails 中的无休止滚动分页,每页一个查询?
典型的 Rails 分页 gem 的问题是它会执行 2 次查询:一项针对您所在的页面,另一项针对总计数。当您不关心有多少页时(例如,在无限滚动中),第二个查询是不必要的(只需在第一个查询中的 LIMIT 子句中添加 1,您就知道是否有更多页)。
是否有一个 gem 可以在没有第二个查询的情况下进行分页?当在大型数据集的 WHERE 子句中应用非索引过滤器时,第二个查询的成本很高,并且对所有各种过滤器建立索引是不可接受的,因为我需要快速插入。
谢谢!
The problem with your typical rails pagination gem is that it does 2 queries: one for the page you're on and one for the total count. When you don't care about how many pages there are (e.g. in an endless scroll), that 2nd query is unnecessary (just add 1 to your LIMIT clause in the 1st query and you know if there are more or not).
Is there a gem that'll do pagination without the 2nd query? The 2nd query is expensive when applying non-indexed filters in my WHERE clause on large datasets and indexing all my various filters is unacceptable because I need my inserts to be fast.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
想通了。使用 will_paginate gem 时,您可以向 AR:Base.paginate 提供您自己的total_entries 选项。这使得第二个查询不会运行。
这适用于足够大的数据集,您只关心最近的条目。
如果您实际上希望到达列表的末尾,则这不一定是可以接受的,因为如果列表大小可以被 per_page 整除,您将在最后一个查询中查询一个空集。无限滚动,这很好。使用手动“加载更多”按钮,当没有更多项目可加载时,您将在最后显示“加载更多”。
Figured it out. When using the will_paginate gem, you can supply your own total_entries option to AR:Base.paginate. This makes it so the 2nd query doesn't run.
This works for sufficiently large datasets where you only care about recent entries.
This isn't necessarily acceptable if you actually expect to hit the end of your list because if the list size is divisible by per_page you're going to query an empty set on your last query. With endless scroll, this is fine. With a manual "load more" button, you'll be displaying "load more" at the very end when there are no more items to load.
正如您所确定的,标准方法是在需要 N 条记录时获取 N+1 条记录,并且如果您在响应中获得多于 N 条记录,则至少可以显示另外一页结果。
您想要执行显式
COUNT(*)
调用的唯一原因是您需要具体了解还需要获取多少条记录。在某些引擎上,这可能需要花费大量时间来计算,因此最好避免这种情况,尤其是在从未直接使用该值的情况下。由于这非常简单,因此您实际上不需要插件来完成它。像
will_paginate
这样的插件更关心可用页面的数量,因此它会执行计数操作。The standard approach, as you've identified, is to fetch N+1 records when you need N and if you get more than N records in the response, there is at least one additional page of results you can display.
The only reason you'd want to do an explicit
COUNT(*)
call is if you need to know specifically how many more records you will need to fetch. On some engines this can take a good chunk of time to compute so it is best avoided especially if the value is never directly used.Since this is so simple, you really don't need a plugin to do it. Plugins like
will_paginate
is more concerned with the number of pages available so it does the count operation.