복붙노트

[RUBY-ON-RAILS] 액티브 레코드 테이블에 대량 삽입 기록

RUBY-ON-RAILS

액티브 레코드 테이블에 대량 삽입 기록

내 Model.create 것을 발견! 문은 내가 한 번에 많은 수의 레코드를 추가 할 때 실행하는 데 너무 많은 시간이 소요되었다. 액티브 - 가져 오기 보았다하지만 (내가 가지고있는 내가 생각하는 아주 일반적인 것입니다) 해시의 배열 작동하지 않았다. 어떻게 성능을 향상시킬 수 있습니까?

해결법

  1. ==============================

    1.액티브 가져 오기 보석을 사용합니다. 우리가 당신을 CSV 파일을 읽고 제품 카탈로그를 생성하는 말을하자 당신은 1000 일괄 레코드를 삽입 할 :

    액티브 가져 오기 보석을 사용합니다. 우리가 당신을 CSV 파일을 읽고 제품 카탈로그를 생성하는 말을하자 당신은 1000 일괄 레코드를 삽입 할 :

    batch,batch_size = [], 1_000 
    CSV.foreach("/data/new_products.csv", :headers => true) do |row|
      batch << Product.new(row)
    
      if batch.size >= batch_size
        Product.import batch
        batch = []
      end
    end
    Product.import batch
    
  2. ==============================

    2.갈 수있는 가장 좋은 방법은 명령을 삽입 다중 행 것을 나에게 보여 주었다와 크리스 종광 덕분에, 그의 2009 기사 @cheald.

    갈 수있는 가장 좋은 방법은 명령을 삽입 다중 행 것을 나에게 보여 주었다와 크리스 종광 덕분에, 그의 2009 기사 @cheald.

    내 초기화에 다음 코드를 추가 / active_record.rb 파일 (...)! Model.import에 (...)! 전화를 내 Model.create을 변경하고 멀리 간다. 몇 가지주의 사항 :

    1) 데이터를 확인하지 않습니다. 2)처럼 읽고 SQL INSERT 명령의 형태를 사용하여 ...

    INSERT INTO <table> (field-1, field-2, ...) 
           VALUES (value-1-1, value-1-2, ...), (value-2-1, value-2-2, ...), ...`
    

    ... 모든 데이터베이스에 대한 올바른 구문 수 있지만, 포스트 그레스와 함께 작동하지 않을 수있다. 당신의 SQL 버전에 해당하는 구문은 코드를 변경하기 어렵지 않을 것입니다.

    내 특정 경우에는, (8기가바이트 RAM, 2.4GHz의 인텔 코어 i5 및 및 SSD와 맥북 프로) 내 개발 컴퓨터에 간단한 테이블에 19K + 기록을 삽입하여 223초에서 갔다 'model.create를!' 7.2 초에 'model.import을!'를 사용.

    class ActiveRecord::Base
    
      def self.import!(record_list)
        raise ArgumentError "record_list not an Array of Hashes" unless record_list.is_a?(Array) && record_list.all? {|rec| rec.is_a? Hash }
        key_list, value_list = convert_record_list(record_list)        
        sql = "INSERT INTO #{self.table_name} (#{key_list.join(", ")}) VALUES #{value_list.map {|rec| "(#{rec.join(", ")})" }.join(" ,")}"
        self.connection.insert_sql(sql)
      end
    
      def self.convert_record_list(record_list)
        key_list = record_list.map(&:keys).flatten.uniq.sort
    
        value_list = record_list.map do |rec|
          list = []
          key_list.each {|key| list <<  ActiveRecord::Base.connection.quote(rec[key]) }
          list
        end
    
        return [key_list, value_list]
      end
    end
    
  3. ==============================

    3.나는 한 번에 1000 개 개의 레코드의 그룹 작업에 코드를 수정, 그래서 나는 기록 (> 10000) 많은 수의 문제로 실행 시작했다. 여기에 새로운 코드에 대한 링크는 다음과 같습니다

    나는 한 번에 1000 개 개의 레코드의 그룹 작업에 코드를 수정, 그래서 나는 기록 (> 10000) 많은 수의 문제로 실행 시작했다. 여기에 새로운 코드에 대한 링크는 다음과 같습니다

    https://gist.github.com/jackrg/76ade1724bd816292e4e

  4. ==============================

    4.또한 액티브 - insert_many 보석을 사용할 수 있습니다. 그냥 객체의 배열을 만들!

    또한 액티브 - insert_many 보석을 사용할 수 있습니다. 그냥 객체의 배열을 만들!

    events = [{name: "Movie Night", time: "10:00"}, {name: "Tutoring", time: "7:00"}, ...]
    
    Event.insert_many(events)
    
  5. ==============================

    5.트랜잭션을 사용하면 많은 대량 삽입 속도!

    트랜잭션을 사용하면 많은 대량 삽입 속도!

    Model.transaction do
        many.times{ Model.create! }
    end
    

    여러 모델이 참여하는 경우, 영향을받는 각 모델에 대한 Model.transaction을 수행합니다

    Model1.transaction do
        Model2.transaction do
            many.times do
                m1 = Model1.create!
                m1.add_model2
            end
        end
    end
    
  6. from https://stackoverflow.com/questions/15317837/bulk-insert-records-into-active-record-table by cc-by-sa and MIT license