当我一次添加大量记录时,我发现运行Model.create!语句需要很长时间。我看过ActiveRecord-Import,但它不能与哈希数组一起工作(这就是我所拥有的,我认为这是很常见的)。如何提高性能?
发布于 2014-05-17 02:16:19
我开始遇到大量记录(> 10000条)的问题,所以我修改了代码,以便一次处理1000条记录。以下是新代码的链接:
发布于 2013-03-10 10:21:44
使用activerecord-import gem。假设您正在读取CSV文件并生成Product目录,并且希望批量插入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发布于 2013-03-10 09:17:11
感谢Chris Heald @cheald在2009年的article,他向我展示了最好的方法是多行插入命令。
将以下代码添加到我的initializers/active_record.rb文件中,将我的Model.create!(...)调用更改为Model.import!(...),然后就可以了。以下是一些注意事项:
1)不验证数据。
2)它使用SQL INSERT命令的形式,读起来像这样...
INSERT INTO <table> (field-1, field-2, ...)
VALUES (value-1-1, value-1-2, ...), (value-2-1, value-2-2, ...), ...`..。这可能不是适用于所有数据库的正确语法,但它适用于Postgres。根据您的SQL版本修改适当语法的代码并不困难。
在我的特殊情况下,将19K+记录插入到我的开发机器(8 8GB内存的MacBook专业版,2.4 and英特尔核心i5和固态硬盘)上的一个简单表中,使用'model.create!‘的时间从223秒缩短到了223秒。到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
endhttps://stackoverflow.com/questions/15317837
复制相似问题