Подтвердить что ты не робот

Выполняет ли ActiveRecord вставку/удаление навалом, когда внутри транзакции?

Что мне нужно:

  • обеспечение атомных обновлений (никакая запись не может обрабатываться 2 раза)
  • массовое удаление для всех выбранных 1000 строк

@queue = Queue.where("col = 1").limit(1000)
ids = []
@queue.each do |row|
    Queue.do_something(row)
    ids << row.id
end

Queue.delete_all("id in (#{ids.join(',')}) ")

ЯВЛЯЕТСЯ ТОЛЬКО КАК

Queue.transaction do
    @queue.each do |row|
        Queue.do_something(row)
        Queue.delete(row.id)
    end
end
4b9b3361

Ответ 1

Для вставок:

ActiveRecord не выполняет объемную вставку при использовании транзакции. Однако это немного ускоряет работу, поскольку использует одну транзакцию для выполнения всех инструкций INSERT, в отличие от одной транзакции в отношении инструкции INSERT.

Итак:

Queue.transaction do 
  @queue.each do |row|
    # an INSERT is done here
  end
end

будет быстрее:

@queue.each do |row|
  # an INSERT is done here
end

Для получения дополнительной информации о том, как реально выполнять массовые вставки, ознакомьтесь с этой статьей.

Для удаления:

Вызов ActiveRecord delete_all - это один оператор SQL DELETE, поэтому, я думаю, вы могли бы рассматривать это как массовое удаление (нет необходимости использовать транзакцию здесь, поскольку он уже инкапсулирован в одну транзакцию ActiveRecord). Это не тот случай, когда вы вызываете delete для каждой записи, что приведет к нескольким операторам SQL DELETE, таким образом, несколько инициированных и совершенных транзакций и общая медленная производительность.

Ответ 2

Я предлагаю вам взглянуть на ActiveRecord Import: https://github.com/zdennis/activerecord-import.

Я использую этот инструмент для вставки от 10 000 до 100 000 строк данных.

books = []
10.times do |i| 
  books << Book.new(:name => "book #{i}")
end
Book.import books

Если вы используете MySQL, он также поддерживает ON DUPLICATE KEY UPDATE, чтобы вы могли разумно вставлять новые/обновлять старые строки. https://github.com/zdennis/activerecord-import/wiki/MySQL:-On-Duplicate-Key-Update-Support