我有一个Rails 3.2应用程序,可跟踪订阅订单的邮件。
基本模型结构是:
订单has_many订阅has_many SubscriptionMailings
每个月都会生成每个订阅邮件的记录,并从这些记录中导出csv文件。
邮寄地址存储在订单级别。
基本上,我选择所有对该月邮寄有效的订阅,并通过它们从订单对象获取邮寄地址。然后我为每个人创建一个新的订阅邮件记录。
现在这个工作正常,因为没有很多订阅,但它很慢。
如何加快这个过程?
答案 0 :(得分:0)
为了优化,你需要从Ruby级别逐步降级到SQL级别。
而不是N+1
选择(1
用于获取所有订阅而N
用于获取每个订阅的所有订单),您可能只能选择1
加入。
SubscriptionMailing.
joins(:subscrtiption).
joins(:order).
where(Order.table_name => { valid: true })
答案 1 :(得分:0)
听起来你想要使用包含来急切加载订单。也许是这样的:
# Subscription.rb
scope :valid_for_month lambda {|month| where(month: month)}
# Elsewhere
valid_subscriptions = Subscription.valid_for_month(Time.now.month).includes(:order)
valid_subscriptions.each do |subscription|
subscription.generate_subscription_mailing
end
更多内容包括:http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
答案 2 :(得分:0)
经过一些研究后,我最终将我的代码包装在一个事务中,而没有进行任何其他更改。
加速了相当多的事情。
在我添加交易之前,代码运行时间超过1分钟,现在大约需要10秒钟。这足以满足我的需求,所以我没有尝试进一步优化。
ActiveRecord::Base.transaction do
# my db stuff here
end