Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails查询优化(消除n+;1个查询)_Ruby On Rails_Ruby_Activerecord_Query Optimization - Fatal编程技术网

Ruby on rails Rails查询优化(消除n+;1个查询)

Ruby on rails Rails查询优化(消除n+;1个查询),ruby-on-rails,ruby,activerecord,query-optimization,Ruby On Rails,Ruby,Activerecord,Query Optimization,我正在做一个项目,有一个复杂的查询需要10秒左右才能执行。我意识到有一个N+1查询正在发生,但我对rails是新手,不知道如何修复它。控制器代码为: def index filters = params.slice(:package_type, :guid) list = packages list = list.where(filters) unless filters.empty? respond_to do |format| format.h

我正在做一个项目,有一个复杂的查询需要10秒左右才能执行。我意识到有一个N+1查询正在发生,但我对rails是新手,不知道如何修复它。控制器代码为:

def index

    filters = params.slice(:package_type, :guid)
    list = packages
    list = list.where(filters) unless filters.empty?

    respond_to do |format|
      format.html { @packages = list.includes(:classification).order(:priority => :asc) }
      format.json { @packages = list.includes(:classification, {channels: [:classification, :genres]}, :extras).order(:priority => :asc) }
    end
  end
包模型具有

class Package < ActiveRecord::Base
  extend FriendlyId


  belongs_to :classification
  has_many :package_channels
  has_many :channels, -> { order(:priority => :asc, :identifier => :asc) }, through: :package_channels
  has_many :package_extras
  has_many :extras, -> { order(:identifier => :asc) },through: :package_extras
以下是视图:index.json.jbuilder

json.cache! ["cache", "#{params["plan_id"]}_packages_index"] do
  json.array! @packages do |package|
    json.partial! 'packages/package_lean', package: package
  end
end

我看不到查询本身,所以我可能无法具体回答这个问题

1.使用即时加载将N+1查询转换为1 一般来说,您的第一步应该是使用急切加载技术来防止N+1查询。很可能您正在请求尚未加载的关联集合(或单个对象)

# controller
def index
  @customers = Customer.active
end

# view
<% @customers.each do |c| %>
  <%= c.name %> # this is fine the object is already in memory from your controller
  <%= c.address %> # this one makes a query to the database
<% end %>
2.确保您有关联外键的索引 另一个好东西是关联外键的索引

add_index :customer, :address_id
在为某些复杂查询构建执行计划时,DB引擎可能会选择不使用此索引,但对于简单查询,情况就是这样

3.使用子弹宝石 有一种叫“坏宝石”的东西。当您开发应用程序时,它将监视您的查询,并通知您何时应添加即时加载(N+1查询)、何时使用不必要的即时加载以及何时应使用计数器缓存。

您是否可以显示控制器的
#packages
方法,以及是否可以添加查看代码?半相关
# controller
def index
  @customers = Customer.active
end

# view
<% @customers.each do |c| %>
  <%= c.name %> # this is fine the object is already in memory from your controller
  <%= c.address %> # this one makes a query to the database
<% end %>
@customers = Customer.active.includes(:address)
add_index :customer, :address_id