次の1回限りのレイクタスクで、ユーザーアカウント(数十万を超える)に基づくデータで埋め戻す必要がある新しいテーブルを作成しています。Railsで新しいテーブルをどのように埋め戻すべきですか?
私がしたことは、2000人のユーザーごとに大きなINSERT文字列を作成し、そのクエリを実行することです。
はここのコードはおおよそ次のようになります。だから私は思ったんだけど
task :backfill_my_new_table => :environment do
inserts = []
User.find_each do |user|
tuple = # form the tuple based on user and user associations like (1, 'foo', 'bar', NULL)
inserts << tuple
end
# At this point, the inserts array is of size at least 20,000
conn = ActiveRecord::Base.connection
inserts.each_slice(2000) do |slice|
sql = "INSERT INTO my_new_table (ref_id, column_a, column_b, column_c) VALUES #{inserts.join(", ")}"
conn.execute(sql)
end
end
、これを行うには良い方法はありますか?私が取ったアプローチの欠点は何ですか?どのように改善するべきですか?もし私がinserts
配列をスライスしておらず、数十万のVALUESタプルを持つ単一のINSERT
を実行したらどうでしょう?その方法の欠点は何ですか?
ありがとうございます!
なぜ、挿入を高速化するためにトランザクションでラップされたMyNewTableメソッドを使用しないのですか?また、現在の実装では、SQLインジェクションまであなたを開きます。 –
ああ、私はあなたが一度に複数のインサートをやっているのを忘れていました。それは確かに高速です(しかし、もしあなたが普通のインサートをそれぞれ1000というトランザクションでラップするとどれくらいの大きさであるかはわかりません)。 –