Ruby on Rails - 插入数据库时​​的效率

时间:2014-10-25 23:17:36

标签: ruby-on-rails

我有一个问题,对你们中的许多人来说可能大部分都很简单。

在我的ruby on rails应用程序中,我会经常将20k +行数据导入数据库。发生这种情况的应用程序的组件是获取一个变量,该变量包含列表中的数据,循环遍历该变量,并在每一行上执行新的Model.create(数据)。

我注意到大约17k行数据需要1.5分钟左右。

基本上,它看起来与此类似:

@items = []
import_file = File.open('file')
data = import_file.read.split("\n")
data.each do |item|
   name = item.scan(/<name>(.*?)<\/name>)[0][0]
   address = item... etc
   @items << {
        :name => name,
        :address => address,
        etc
   }
end

@items.each do |row|
   Model.create(row)
end

在rails服务器控制台中进行监控时,我显然可以看到所有17k插入,并且在控制台中监控时也需要更长的时间来删除。

我确定这是非常低效的,所以我来看看是否有人有任何建议,或者这对于导入的数据量是否正常。

1 个答案:

答案 0 :(得分:1)

这种大量/大量插入的好方法似乎是activerecord-import。 有人也提出了benchmark

根据the introductory example你可以这样做:

@items = []
import_file = File.open('file')
data = import_file.read.split("\n")
data.each do |item|
   name = item.scan(/<name>(.*?)<\/name>)[0][0]
   address = item... etc
   @items << Model.new(
        :name => name,
        :address => address,
        etc
   )
end

Model.import(@items)

手动,单插入方式:

@items = []
import_file = File.open('file')
data = import_file.read.split("\n")
data.each do |item|
   name = item.scan(/<name>(.*?)<\/name>)[0][0]
   address = item... etc
   @items << "(#{name}, #{address},...)"
end

sql = "INSERT INTO models (`name`, `address`, ...) VALUES #{@items.join(", ")}"
ActiveRecord::Base.connection.execute(sql)
相关问题