Как оптимизировать дублирование / клонирование ActiveRecord :: Relation - PullRequest
0 голосов
/ 28 января 2019

Я хочу клонировать список 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

Может быть, есть лучший способ дублировать список записей сразу, а затем обновить все их одним запросом.Я пытался Google, но до сих пор не повезло.

Ответы [ 3 ]

0 голосов
/ 28 января 2019

Если я правильно понял, вы хотите дублировать объекты, которые удовлетворяют условию

(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 голосов
/ 30 января 2019

Короткий ответ - использовать single insert statement вместо multiple inserts, даже если он находится в одной БД transaction.

И bulk_insert gem поможет вам сделать это.(Спасибо arieljuod )

0 голосов
/ 28 января 2019

Если вы хотите сделать это как можно быстрее, тогда 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.

Если у вас есть какие-либо магические столбцы рельсов (созданы, обновлены и т. Д.), Их нужно будет добавить вручную в SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...