如何调试和加速缓慢的has_one关联加载?

时间:2016-08-24 12:12:38

标签: ruby-on-rails ruby-on-rails-4 rails-activerecord

TL; DR

@payment.order # takes from 3 to 15 seconds, unacceptable

Postgres数据库中有1757k订单和640k付款 如何调试为什么加载关联需要这么长时间,以及如何使其更快? 如果数据库索引是问题,如何验证是否是这种情况;如何重建索引?

讨论

我有这两种传统模式:

class Payment < ActiveRecord::Base
  has_one :order
end

class Order < ActiveRecord::Base
  # SCHEMA
  # t.references :payment, index: true

  belongs_to :payment
end

我知道如果付款属于订单会更正确,但这就是应用程序是如何变化的。

历史记录冗长且复杂,payment_id orders表已被删除,恢复并add_index - ed,在批处理任务中更改了值。

在一个payment_id字段删除和恢复后,我注意到在控制台中调用一个简单的关联加载需要很长时间

@payment.order    

由于访问此关联对于应用程序性能至关重要,因此我覆盖了vanilla Rails协会

class Payment < ActiveRecord::Base
  # has_one :order # too slow!

 def order
    return nil if self.new_record?
    return @order ||= Order.where(payment_id: self.id).limit(1).last # takes just 0.3s  
 end

现在负载比以前更快,但是,当然,getter方法的行为不像真正的关联,具体来说,我不能使用Payment.joins(:order)

如何恢复关联并使其具有高效性?

0 个答案:

没有答案