2017-07-20 5 views
0

J'ai ces deux tables installations et clients. installations a environ un million de disques, avec environ 400k clientsUtilisation de la RAM 99% lors de la tentative de générer csv pour un million d'enregistrements Rails

class Installation < ApplicationRecord 
    belongs_to :client, optional: true 
end 

et

class Client < ApplicationRecord 
    has_many :installations 
end 

Je dois générer un csv dans lequel il y aura des millions d'installations dossiers dont le nom d'utilisateur et LINK_TO_PROFILE du client lié (si présent)

Code

pour générer CSV est

require 'csv' 
    def self.generate_csv 
    attributes = %w{ app_identifier app_name device_type installation_id app_version time_zone created_date updated_date username link_to_profile } 

     CSV.generate(headers: true) do |csv| 
     csv << attributes 

     Installation.all.each do |installation| 
     data = [installation.app_identifier, installation.app_name , installation.device_type , installation.db_id , installation.app_version , installation.time_zone , installation.created_date , installation.updated_date ] 
     if installation.client.present? 
      data << installation.client.username 
      data << installation.client.link_to_profile 
     end 
     csv << data 
     end 
    end 
    end 

donc à chaque installation, son client respectif (si présent) est également chargé pour obtenir son nom d'utilisateur et link_to_profile

J'ai 8 Go de RAM, Lorsque j'appelle generate_csv, l'utilisation de la RAM est de 20%. il commence à augmenter et après un certain temps comme un Lac Records il atteint environ 99,7% et que l'échange passe à 50% et le système se bloque, pas de traitement supplémentaire.

Quel est le problème ici et comment puis-je résoudre ce problème?

+0

Avez-vous vérifié [lots] (http://api.rubyonrails.org/classes/ActiveRecord/Batches.html)? – jvillian

+0

ne les a pas essayés, mais le chargement avide a fonctionné –

Répondre

2

Vous pouvez essayer un certain chargement impatient:

require 'csv' 
def self.generate_csv 
    attributes = %w{ app_identifier app_name device_type installation_id app_version time_zone created_date updated_date username link_to_profile } 

    CSV.generate(headers: true) do |csv| 
    csv << attributes 

    Installation.includes(:client).each do |installation| 
     data = [installation.app_identifier, installation.app_name , installation.device_type , installation.db_id , installation.app_version , installation.time_zone , installation.created_date , installation.updated_date ] 
     if installation.client 
     data << installation.client.username 
     data << installation.client.link_to_profile 
     end 
     csv << data 
    end 
    end 
end 
+0

Désolé mais avez-vous changé n'importe quelle partie de mon code? –

+0

une autre chose, j'ai cherché et essayé Installation.find (: all,: include =>: clients), mais il donne erreur –

+0

'Installation.includes (: client) .' et' si installation.client' –