【问题标题】:Rails: will_paginate run extra SQL query when calling page_entries_infoRails: will_paginate 在调用 page_entries_info 时运行额外的 SQL 查询
【发布时间】:2016-01-23 08:31:27
【问题描述】:

我的应用程序使用 rails '3.2.20'、mysql2 '0.3.20' 和 will_paginate '3.0.7'

我正在尝试加载用户记录

@users = User.paginate(:page => params[:page], :per_page => 20)

以下在控制台中执行的查询

User Load (0.3ms)  SELECT `users`.* FROM `users` LIMIT 20 OFFSET 0
(0.3ms)  SELECT COUNT(*) FROM `users` 

一般会为集合和计数运行两个查询

但在视图中使用 page_entries_info 时,我又多了一个查询

User Load (0.3ms)  SELECT `users`.* FROM `users` LIMIT 20 OFFSET 0
(0.3ms)  SELECT COUNT(*) FROM `users` 
User Load (0.2ms)  SELECT `users`.* FROM `users` LIMIT 1 OFFSET 0

希望最后一个查询不要在任何地方使用。

我只是用一个简单的例子来说明,但是我的应用程序执行带有更多连接和包含的大型查询。

不必要的查询可能会降低性能。

这只发生在 will_paginate '3.0.3' 之后

是错误/功能吗?如何避免这个额外的查询?

【问题讨论】:

    标签: ruby-on-rails-3 ruby-on-rails-3.2 rubygems will-paginate


    【解决方案1】:

    为了防止 will_paginate 生成自己的计数查询,请使用 total_entries 参数:

    @users = User.all
    entries = @users.size
    @users.paginate(:page => params[:page], :per_page => 20, :total_entries => entries)
    

    【讨论】:

      【解决方案2】:

      will_paginate 正在进行额外的查询,因为 Rails 延迟执行查询。以下是the method的实现:

      def page_entries_info(collection, options = {})
        model = options[:model]
        model = collection.first.class unless model or collection.empty? # <= this line
        ...
      end
      

      如果在执行该行之前collection 尚未加载,rails 将对collection.firstcollection.empty? 进行额外查询。解决方案是您传递模型,以便 will_paginate 不必评估它:

      page_entries_info @users, model: 'user'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-30
        • 2014-06-02
        • 1970-01-01
        • 1970-01-01
        • 2016-11-26
        • 1970-01-01
        • 2021-05-19
        • 1970-01-01
        相关资源
        最近更新 更多