慢速将CSV导入数据库

时间:2017-03-26 22:22:16

标签: ruby-on-rails ruby csv activerecord

我有一个用于更新数据的CSV文件。更新不超过15.000条记录需要很长时间(约10分钟)。 这是我使用的代码:

task csv_updater_so: :environment do
    require 'csv'
    counter = 0
    time = Benchmark.realtime do
        save_folder = Rails.root.join('path_to_file')
        CSV.foreach(save_folder, encoding:'iso-8859-1:utf-8', col_sep: ';', :quote_char => "\x00", headers: true) do |row|
            #If the item is in the db I update its values
            if item = Item.find_by_internal_code(row[4]) 
                item.update(:price => row[9], :stock_b => row[10]) 
            end
            counter += 1
            print "updated items => #{counter}" + "\r"
        end
    end
end

我觉得很奇怪,从xml文件更新相同的模型只需要几秒钟。我做错了吗?

我也试过

task csv_updater_so: :environment do
    require 'csv'
    counter = 0
    time = Benchmark.realtime do
        save_folder = Rails.root.join('path_to_file')
        updateable_items = CSV.foreach(save_folder, encoding:'iso-8859-1:utf-8', col_sep: ';', :quote_char => "\x00", headers: true).map do |row|
            if item = Item.find_by_internal_code(row[4]) 
                item.update(:price => row[9], :stock_b => row[10]) 
            end
            counter += 1
            print "updated items => #{counter}" + "\r"
        end
        Item.import(updateable_items)
    end
end

1 个答案:

答案 0 :(得分:1)

你的问题是你做你的方式基本上是在每个插页上做一个事务,所以它自然会很慢。

因此,为避免将CSV文件转换为SQL COPY命令,我的建议是使用activerecord-import gem。 它将为您处理关联并按模型对插入进行分组。此外,由于它在单独的gem中提供对数据库的支持,因此您可以利用数据库的一些不错的功能,例如PostgreSQL中的Arrays。