1

以下に List モデルがあります。これには、受信者との has_and_belongs_to_many 関連付けがあります。このメソッドの目的は、(初期パラメーター)make_recipient_listsの解析済み csv をこの形式で保存することです。numbers[[num1],[num2],[num3]...]

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
4

2 に答える 2

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
于 2013-07-27T07:11:54.020 に答える
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

それが役立つことを願っています。ありがとう。

于 2013-07-27T07:18:06.283 に答える