dimanche 13 septembre 2015

Delete faster 300K associated objects on activeadmin (Rails 4, Activeadmin)

When creating a model Deal, I use an after_create to create prizes on the DealPrize table.

Deal and DealPrize have a belong to/has_many relations: a Deal has many Deal prizes and a Dealprize belongs to a Deal.

It works like this: inside Deal, I have a column 'prize-number' and I use an after_create so that every time the admin creates a new deal, the app takes this prize_number column, and create this volume of prizes (inserting as many rows as necessary=> often more than 300,000) inside the DealPrize table.

So I create a Deal, and automatically, the app creates a huge number of associated objects (prizes) say 300,000.

The problem is when I delete the Deal, I want to delete all associated prizes. With active admin, I just press 'delete' and it works fine thanks to the dependent: :destroy. If the prize number is like 200, it works fine but for 300K associated objects/rows, it is very slow. It takes 15 minutes.

How can I speed it up ? how can I override/boost ActiveAdmin delete function in order to delete the 300K associated prizesfaster?

Could I use transactions or batched deletes ?

modals Deals.rb

has_many   :deal_prizes,  dependent: :destroy 

after_create :create_deal_prizes

CONNECTION = ActiveRecord::Base.connection.raw_connection

    def create_deal_prizes
      begin 
        CONNECTION.describe_prepared('yokoatxz')
      rescue PG::InvalidSqlStatementName
        CONNECTION.prepare('yokoatxz', 'INSERT INTO deal_prizes (deal_id,created_at,updated_at,admin_user_id) values ($1, $2, $3, $4)') 
      end

      Deal.transaction do  
        self.prizes_number.times do |i| 
          CONNECTION.exec_prepared('yokoatxz',  [ { value: self.id},
                                                  { value: '2009-01-23 20:21:13' },
                                                  { value: '2009-01-23 20:21:13' },
                                                  { value: self.admin_user_id }
                                                ] )
        end
      end
    end

Thanks for your help, Mathieu

Aucun commentaire:

Enregistrer un commentaire