2013-07-27 55 views
1

我有一个列表模型下面,它有一个has_and_belongs_to_many与收件人关联。方法make_recipient_lists的目的是以这种格式[[num1],[num2],[num3]...]保存解析的csv numbers(初始参数)。Rails模型优化

add_recipients通过查找现有收件人然后将其添加到列表或创建新的收件人的工作。

整个过程对于28分钟的小数量,20k数字来说效果很好。然而,数字越大,指数性所需的时间越长,70k花了14小时。可能是因为它正在检查缓存的重复项current_lists

问题是,有什么办法可以让这个更快吗?我可能接近这个问题是错误的。谢谢!

class List < ActiveRecord::Base 

#other methods above 

    def make_recipient_lists(numbers,options) 
    rejected_numbers = [] 
    account = self.user.account 

    #caching recipients 
    current_recipients = self.recipients 

    numbers.each do |num| 
     add_recipient(num[0], current_recipients) 
    end 

    end 

    def add_recipient(num, current_recipients) 
    account = self.user.account 

    recipient = current_recipients.where(number:num, account_id: account.id).first 
    recipient ||= current_recipients.create!(number:num, account_id: account.id) 

    recipient 
    end 

end 

回答

0

你可以做这样的事情。我没有测试过这个,但你明白了。

def make_recipient_lists(numbers, options) 
    rejected_numbers = [] 
    account = self.user.account 
    existing_numbers = self.recipients.where(number: numbers, account_id: account.id).map(&:number) 
    new_records = (numbers - existing_numbers).map {|n| {number: n, account_id: account.id, list_id: self.id} } 

    Recipient.create new_records 
    end 
+0

嗨@Neo,我打算在一段时间尝试一下,但它看起来很有希望。谢谢。 –

+0

在代码中添加了很多,但这对我有很大的帮助。谢谢@Neo! –

0

我想,你应该使用rails active_record查询接口。你可以使用方法find_or_create方法:它会让你的查询更快。改变你的方法是这样的,并检查时间差异:

def make_recipient_lists(numbers,options) 
    rejected_numbers = [] 
    account = self.user.account 

    #caching recipients 
    current_recipients = self.recipients 

    numbers.each do |num| 
     self.recipients.find_or_create_by(number: num, account_id: account.id)  
    end 
end 

希望它会有所帮助。谢谢。