如何复制在最优化的方式/克隆的ActiveRecord ::关系

问题描述 投票:0回答:3

我想克隆一个优化的方式ActiveRecord对象的列表。也许,我使用的方式已经被优化,但我需要加快这一进程。所以这是我的代码

ActiveRecord::Base.transaction do
  data = MyModel.where(column_1: 'x')
  data.each do |item|
    new_item = item.dup
    new_item.column_2 = 'y'
    new_item.save!
  end
end

也许有一次,然后用一个查询更新所有这些重复的记录列表的一个更好的办法。我试图谷歌,但没有运气至今。

ruby-on-rails ruby activerecord ruby-on-rails-5
3个回答
0
投票

如果我的理解没错,你要复制符合条件的对象

(column_1: 'x')

你可以试试这个方法,看起来像它会做同样的

MyModel.where(column_1: 'x').find_each { |u| u.dup.update(column2: 'y') }

但慢一点(基准N = 1000)

<Benchmark::Tms:0x00007f96e6a1b970 @label="**dup.update**", @real=6.75463099999979, @cstime=0.0, @cutime=0.0, @stime=0.331546, @utime=2.2468139999999996, @total=2.5783599999999995>,

<Benchmark::Tms:0x00007f96e8cb23f8 @label="**dup.save!**", @real=6.470054999999775, @cstime=0.0, @cutime=0.0, @stime=0.32828900000000005, @utime=1.972385, @total=2.300674>

0
投票

简短的回答是改为使用single insert statementmultiple inserts即使如果它在一个DB transaction

bulk_insert宝石将帮助你做到这一点。 (感谢arieljuod


0
投票

如果你想尽快做,那么SQL是要走的路。

像这样的东西会做:

ActiveRecord::Base.connection.execute <<-SQL
   INSERT INTO my_models (column_1, column_2, column_3, ..)
      SELECT column_1, 'y', column_3, ..
      FROM my_models WHERE column_1 = 'x';
SQL

这应该在PostgreSQL和MySQL工作。

如果您有任何轨道魔法列(created_at,等的updated_at),他们将不得不在SQL手动添加。

© www.soinside.com 2019 - 2024. All rights reserved.