我有类似下面的内容:
module Bar < ActiveRecord::Base
belongs_to :foo
...
module Foo < ActiveRecord::Base
has_many :bars, dependent: :destroy
def build_bars
1000.times do |i|
bars.build(num: i)
end
end
def create_default_bars!
build_bars
save
end
请注意 Foo#build_bars
很便宜。即使它循环 1000 次,也只需要很少的时间。但是,一旦您点击保存
,ActiveRecord 突然决定执行 1000 次插入,这非常慢。
我如何编写自定义 save_the_bars
方法,以便它对我建立的所有 bars
执行单个批量 INSERT 查询(我提醒你,1000 build
显然非常便宜),但是在这个例子中哪个功能可以替代 save
?
我期待按照这篇博文的建议 #3 给出的答案:
但由于我的示例使用 build
并依赖于一些稍微重要的 rails 魔法,因此如何转换它并不是很明显。基准测试的奖励积分!
最佳答案
我会尝试 activerecord-import
gem 。
def save_the_bars(bars)
Bars.import bars
end
This call to import does whatever is most efficient for the underlying database adapter. Pretty slick, eh?
奖励积分:Benchmarks
提问者在这里,劫持这个答案,详细说明我按照上述建议做了什么:
def build_bars
built_bars = []
1000.times do |i|
built_bars << bars.build(num: i)
end
built_bars
end
def create_default_bars
save
Bar.insert built_bars, validate: false
reload
end
这以相对较少的努力提供了不错的加速。我仍然怀疑可以有更多的加速(通过利用 insert
的细微差别),但我现在对此感到满意。在我的用例中,关闭验证是安全的,因为生成所有 Bar
的方法保证生成有效的。
关于ruby-on-rails - Rails 批量构建和保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18642528/