2013-07-27 158 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 

希望它會有所幫助。謝謝。