aDev
aDev

Reputation: 43

Bulk deleting entries from a model efficiently

Let's say I have a model Books. I want to remove all entries which are created before a certain date and books that meet a certain condition, books without an ISBN.

Would fetching ids and running a delete job in batches be the most efficient way? Note:- I am aware that delete is faster than destroy_all but I don't wish to skip callbacks in this case.

Example

Books.select(:id).where(isbn: nil).find_in_batches(batch_size: 1000) do |ids|
  Books.where(id: ids).destroy_all
end

Upvotes: 1

Views: 1622

Answers (1)

João Fernandes
João Fernandes

Reputation: 731

destroy_all is the same as:

books.each(&:destroy)

As you can see in source code

So you can just:

Books.select(:id).where(isbn: nil).find_in_batches(batch_size: 1000) do |books|
  # since destroy_all is only a ActiveRecord::Relation method
  books.each(&:destroy)
end

This is the minimal query setup to do this the most efficiently way and yet getting your callbacks fired.

Note: if your callbacks need any other attribute than id loaded, you should add it to your select query.

Upvotes: 1

Related Questions