Ruby on rails 如何在Rails中回填新表?
我正在创建一个新表,该表需要使用基于用户帐户(超过几十个)的数据进行回填,并执行以下一次性rake任务 我决定为每2000个用户创建一个大的插入字符串,并执行该查询 下面是代码的大致外观:Ruby on rails 如何在Rails中回填新表?,ruby-on-rails,postgresql,query-optimization,rails-activerecord,Ruby On Rails,Postgresql,Query Optimization,Rails Activerecord,我正在创建一个新表,该表需要使用基于用户帐户(超过几十个)的数据进行回填,并执行以下一次性rake任务 我决定为每2000个用户创建一个大的插入字符串,并执行该查询 下面是代码的大致外观: task :backfill_my_new_table => :environment do inserts = [] User.find_each do |user| tuple = # form the tuple based on user and user ass
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
task:backfill\u my\u new\u table=>:environment do
插入=[]
User.find_每个do|用户|
tuple=#根据用户和用户关联形成tuple,如(1,'foo','bar',NULL)
插入取决于您使用的PG版本,但在大多数情况下,将数据批量加载到表中就足够了:
- 尽可能使用而不是插入李>
- 如果使用多个插入,请禁用自动提交并在单个事务中包装所有插入,即
BEGIN;插入。。。;插入。。。;承诺代码>
- 禁用目标表的索引和检查/约束李>
- 禁用表触发器李>
- 所以它变成了(从第9.5页开始,别忘了在数据导入后打开日志记录),或者增加了,所以不会被淹没
20k行对于PG来说并不是什么大问题,因此在一个事务中插入2k个切片就可以了,除非涉及一些非常复杂的触发器/检查。它也值得一读
UPD:和,摘录:
因此,如果您希望尽可能快地插入数据,请使用copy(或者更好的是使用pgbulkload)。如果出于任何原因不能使用“复制”,则使用多行插入(8.2中新增!)。然后,如果可以,将它们捆绑到事务中,并使用准备好的事务,但一般来说,它们不会给您带来太多
为什么不使用事务中包装的MyNewTable方法来加速插入?另外,当前的实现为SQL注入打开了大门。哦,我错过了您同时进行多个插入的机会。这确实会更快(但如果在一个1000个事务中包装普通插入,则不确定速度有多快)。