Kaminari 可以在不使用 COUNT(*) 查询访问数据库的情况下工作吗?
我的应用程序的数据库很大,计算项目所需的时间比获取项目本身要长得多,从而导致性能问题。
也欢迎对其他具有大型数据集的分页解决方案提出建议。
Kaminari 可以在不使用 COUNT(*) 查询访问数据库的情况下工作吗?
我的应用程序的数据库很大,计算项目所需的时间比获取项目本身要长得多,从而导致性能问题。
也欢迎对其他具有大型数据集的分页解决方案提出建议。
一般分页器需要知道总记录数来显示链接,但有时我们不需要总记录数,只需要“上一页”和“下一页”链接。对于这样的用例,Kaminari 提供without_count
了创建可分页集合而不计算所有记录数的模式。当您处理非常大的数据集时,这可能会有所帮助,因为在 RDBMS 上对大表进行计数往往会变慢。
只需添加.without_count
到您的分页对象:
User.page(3).without_count
在您的视图文件中,您只能使用如下简单的帮助器,而不是全功能的paginate
帮助器:
<%= link_to_prev_page @users, 'Previous Page' %>
<%= link_to_next_page @users, 'Next Page' %>
好吧,Kaminari 或 will_paginate 需要以某种方式计算 total 以确定要呈现的 total_pages。这是不可避免的。我的解决方案是查看数据库查询并尝试对其进行优化。这就是要走的路。
(此答案已过时,请参阅上面的答案)
我们有一个案例,我们确实想要一个总计数,但不想为它访问数据库——我们的 COUNT 查询在某些情况下需要几秒钟,即使索引很好。
因此,我们在父表中添加了一个计数器缓存,使用触发器使其保持最新,并覆盖total_count
Relation 对象上的单例:
my_house = House.find(1)
paginated = my_house.cats.page(1)
def paginated.total_count
my_house.cats_count
end
...以及所有需要计数的东西都可以在不进行查询的情况下工作。
这是一件不寻常的事情。维护计数器缓存有一些成本。如果您对分页数据进行进一步的关系处理,可能会产生奇怪的副作用。覆盖单例方法有时会使调试变成一场噩梦。但是谨慎使用并且记录良好,您可以通过良好的性能获得您想要的行为。