Rails创建单个记录VS创建多个记录PERFOMANCE差异

问题描述 投票:0回答:2

这种方法之间有速度差异吗? (POSTGRESQL)

第一

products = [{...},{...},...]
products.each { |p|
  Product.create(p)
}

第二

products = [{...},{...},...]
Product.create(products)

每条记录的两种方法都会产生两个查询:

1) INSERT INTO "products" VALUES (..)
2) UPDATE "products" SET "updated_at"...
ruby-on-rails postgresql performance activemodel
2个回答
1
投票

两者之间的表现应该几乎没有差别。

如果你检查the implementation,你可以看到,如果你将一个数组传递给.create,它会遍历数组并为数组中的每个元素调用.create

module ActiveRecord
  module Persistence
    extend ActiveSupport::Concern
    module ClassMethods
      # ...
      def create(attributes = nil, &block)
        if attributes.is_a?(Array)
          attributes.collect { |attr| create(attr, &block) }
        else
          object = new(attributes, &block)
          object.save
          object
        end
      end
      # ...
   end
end

ActiveRecord实际上并不实现大量插入。我的意思是在一个语句中插入多行:

INSERT INTO products (name, description) VALUES ('Soap', '100% whale based.'),('Shampoo', '...') 

在给定足够记录的情况下,可以更快一个数量级。

但您可以编写自己的SQL来完成此任务:

class Product
  def self.mass_insert(attributes)
    values = products.map("(#{attributes[:name]}, #{attributes[:description]})").join(',')
    self.connection.execute("INSERT INTO products (name, description) VALUES #{values}")
  end
end

请注意,此简单示例不会清理输入,并且容易受到SQL注入攻击。


0
投票

max是对的。这是本地解决方案。

但我发现activerecord-import gem做同样的事情 - 批量对象导入。

© www.soinside.com 2019 - 2024. All rights reserved.