我发现我的Model.create!
声明服用很长一段时间,当我在一次加入了大量的记录运行。 看着ActiveRecord的进口 ,但它并没有与散列数组的工作(这是我和我认为这是很常见的)。 我怎样才能提高性能?
Answer 1:
使用ActiveRecord的进口宝石。 让我们假设你正在阅读的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
Answer 2:
感谢Chris希尔德@cheald为他的2009年的文章 ,以显示我去的最好办法是多行插入命令。
下面的代码添加到我的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 +记录到一个简单的表,我的机器(的MacBook Pro配备8GB内存,2.4GHz的英特尔酷睿i5和和SSD)上使用从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
Answer 3:
我开始跑步与大量的记录(> 10000)的问题,所以我修改了代码,同时在1000个记录组的工作。 这里是新代码的链接:
https://gist.github.com/jackrg/76ade1724bd816292e4e
Answer 4:
您还可以使用ActiveRecord的-insert_many宝石。 只是让对象的数组!
events = [{name: "Movie Night, time: "10:00"}, {name: "Tutoring", time: "7:00"}, ...]
Event.insert_many(events)
Answer 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
文章来源: Bulk Insert records into Active Record table