Есть ли разница в скорости между этими методами? (ПОСТГРЕSQL)
Первый
products = [{...},{...},...]
products.each { |p|
Product.create(p)
}
Второй
products = [{...},{...},...]
Product.create(products)
Оба метода для каждой записи делают два запроса:
1) INSERT INTO "products" VALUES (..)
2) UPDATE "products" SET "updated_at"...
но если я должен предположить, второй, по крайней мере, не медленнее. И это может быть намного быстрее (если все создания продукта будут выполняться в одном INSERT).
Кажется, в вашей модели определен обратный вызов, который вызывает второй запрос на обновление. На самом деле должен быть только один запрос на вставку. Это действительно не имеет ничего общего с первой частью вашего вопроса.
Между ними не должно быть практически никакой разницы в производительности.
Если вы отметите реализация, вы увидите, что если вы передаете массив .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.
Максимум прав. Это локальное решение.
Но я нашел activerecord-import
драгоценный камень, который делает то же самое - импортирует объемные объекты.
"Есть ли разница в скорости" - это то, что можно мера (и точно знать)