model.association.delete_all performance issue - Rails 3.2.3 #6289

Closed
njakobsen opened this Issue May 12, 2012 · 7 comments

Comments

Projects
None yet
5 participants
Contributor

njakobsen commented May 12, 2012

This is a very similar issue to #3672. Instead of the problem being on the :dependent => :delete_all callback, it occurs when calling delete_all on an association. The problem is that instead of returning the count of the number of deleted objects like :delete_all does on an ActiveRecord model, calling :delete_all on an ActiveRecord association returns an array of all the deleted objects.

I am running into an issue when I try to destroy all 30,000 objects associated with my main model and Rails tries to instantiate each one. The whole point behind :delete_all is that for performance reasons it's purely a database call, and no ActiveRecord objects should be instantiated.

See https://gist.github.com/2668335 for an example of the bug.

Contributor

gmile commented May 12, 2012

Indeed, I've ran the code in gist and it appears to be extremely slow

Contributor

njakobsen commented May 13, 2012

Maybe @jonleighton can weigh in on this as he was able to fix the other similar bug.

jonleighton added a commit that referenced this issue May 18, 2012

Perf: Don't load the association for #delete_all.
Bug #6289

Conflicts:

	activerecord/test/cases/associations/has_many_associations_test.rb
Member

jonleighton commented May 18, 2012

Fixed in master and 3-2-stable by the above commits.

Contributor

njakobsen commented May 18, 2012

Excellent! I'll be able to unhack all my codes.

Member

jonleighton commented Jun 7, 2012

I am afraid you might need to rehack your codes until Rails 4 is out: 959fb8e

Contributor

njakobsen commented Jun 7, 2012

Thanks for the heads up.

I'm just trying to interpret the decision from reading the commit log for 959fb8e. My understanding is that for some reason, people used delete_all instead of destroy_all and expected callbacks to work since rails 2.3? And that this is a major change that doesn't belong in a small point release, so it's being left for Rails 4.0?

fenelon commented Nov 6, 2012

On Rails 3.2.8:

Note that "deleting from s3" is in a before_destroy callback. The delete_all spec says it doesn't trigger any callbacks.

irb(main):006:0> h = Hotel.find(40069)
irb(main):007:0> h.images.delete_all
   (0.1ms)  BEGIN
deleting from s3
  SQL (0.4ms)  DELETE FROM `hotel_images` WHERE `hotel_images`.`id` = 7388
deleting from s3
  SQL (0.3ms)  DELETE FROM `hotel_images` WHERE `hotel_images`.`id` = 7389
deleting from s3
  SQL (0.3ms)  DELETE FROM `hotel_images` WHERE `hotel_images`.`id` = 7390
deleting from s3
  SQL (0.2ms)  DELETE FROM `hotel_images` WHERE `hotel_images`.`id` = 7391
deleting from s3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment