【问题标题】:Optimizing ActiveRecord query Attribute with where使用 where 优化 ActiveRecord 查询属性
【发布时间】:2015-12-29 03:44:45
【问题描述】:

我有一个具有project_leadproject_operative_lead 这两种方法的模型。

每当我尝试获取这两个属性时,我都会收到大量查询。即使我正在尝试使用包含。

这是我的模型:

class Project < ActiveRecord::Base
  has_many :project_sales_contributions, dependent: :destroy
  has_many :sales_contributors, through: :project_sales_contributions, source: 'employee'

  has_many :project_contributions,  dependent: :destroy
  has_many :contributors, through: :project_contributions, source: 'employee'

  accepts_nested_attributes_for :project_customer_contacts,
    :project_contributions,
    :project_sales_contributions,
    allow_destroy: true,
    reject_if: :all_blank

  def project_lead
    project_contributions.where(role: 'lead').map { |e| e.employee.name }
  end

  def project_operative_lead
    project_contributions.where(role: 'operative_lead').map { |e| e.employee.name }
  end

end

这是我的包含声明: Project.includes(:customer, project_contributions: [ :employee ]).all

但是我仍然得到 n+1 个查询。

有什么办法可以减少查询次数?

【问题讨论】:

  • 嘿你可以用你的方法project_contributions.includes(:employee).where(role: 'lead').map { |e| e.employee.name }实际上在你的地图是N+1查询

标签: sql ruby-on-rails performance activerecord


【解决方案1】:

where 子句作用于ActiveRecord 对象。 project_contributionsEnumerable,因此您可以对其执行迭代方法,例如 mapselect 等。不必再次查询该表即可获得所需的内容。

顺便说一句,为什么不在这里使用joins 呢?您可以使用joins 而不是include。使用includes,您正在急切地加载customer 模型,这在您的情况下是一种过度杀伤,因为您没有使用Customer 模型的属性,我认为。只是我的两分钱。

Project.joins(:customer, project_contributions: [ :employee ]).all

【讨论】:

    【解决方案2】:

    您再次查询了 project_contributions,因此它破坏了包含,您可以尝试选择:

    project_contributions.select{ |e| e.role == 'lead' }.map{ |e| e.employee.name }
    

    【讨论】:

      猜你喜欢
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 2015-09-13
      • 2017-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多