rails ruby 中的预加载优化
Eager Loading Optimization in ruby on rails
我有一个产品 has_many 变体。一个变体属于一个产品。我想显示产品名称(可以在 Product 中找到)以及价格和数量(可以在 Variants 中找到)。
Product table:
-id
-title
-description
Variants table:
- id
- is_active(boolean)
- price
- quantity
- product_id
这就是 table 的样子。这是我的尝试
def index
@products =Product.all
@display = []
@products.each do |product|
@children = product.variants.where(is_active: true).order(:price).
select(:id,:price,:quantity).first
if @children.present?
@display << {
id: product.id,
title: product.title,
description: product.description,
price: @children.price,
quantity: @children.quantity,
variant_id: @children.id
}
end
end
@display = Kaminari.paginate_array(@display).page(params[:page])
end
我需要最大限度地优化它。这让我想到了我的第一个问题。我怎样才能更好地优化它。
我的第二个问题为什么当我做 @products = Product.all.includes(:variants) 它实际上会增加加载时间而不是减少它,因为我确实在整个 @products 数组中获得了该迭代中每个产品的变体(所以它应该算作 N+1,我得到的每个产品都有变体)?
将我的@products 数组拆分为 4 个并使 4 个线程填充显示是个好主意吗?
你应该写成;
def index
@display = Varient.joins(:product).where(is_active: true).order(:price).select('products.id as id, products.title, products.description, price, quantity, variants.id as variant_id')
end
您的代码没有使用预先加载的数据,这就是为什么添加 include 会减慢速度 - 这只是额外的工作。
一般来说,如果您调用查询方法(where
、order
等),rails 不能使用预先加载的数据。相反,您可以创建一个新的关联:
has_many :active_variants, -> { where(is_active: true).order(:price) }, class_name: "Variant"
然后预加载并使用此关联而不是变体关联。
我有一个产品 has_many 变体。一个变体属于一个产品。我想显示产品名称(可以在 Product 中找到)以及价格和数量(可以在 Variants 中找到)。
Product table:
-id
-title
-description
Variants table:
- id
- is_active(boolean)
- price
- quantity
- product_id
这就是 table 的样子。这是我的尝试
def index
@products =Product.all
@display = []
@products.each do |product|
@children = product.variants.where(is_active: true).order(:price).
select(:id,:price,:quantity).first
if @children.present?
@display << {
id: product.id,
title: product.title,
description: product.description,
price: @children.price,
quantity: @children.quantity,
variant_id: @children.id
}
end
end
@display = Kaminari.paginate_array(@display).page(params[:page])
end
我需要最大限度地优化它。这让我想到了我的第一个问题。我怎样才能更好地优化它。
我的第二个问题为什么当我做 @products = Product.all.includes(:variants) 它实际上会增加加载时间而不是减少它,因为我确实在整个 @products 数组中获得了该迭代中每个产品的变体(所以它应该算作 N+1,我得到的每个产品都有变体)?
将我的@products 数组拆分为 4 个并使 4 个线程填充显示是个好主意吗?
你应该写成;
def index
@display = Varient.joins(:product).where(is_active: true).order(:price).select('products.id as id, products.title, products.description, price, quantity, variants.id as variant_id')
end
您的代码没有使用预先加载的数据,这就是为什么添加 include 会减慢速度 - 这只是额外的工作。
一般来说,如果您调用查询方法(where
、order
等),rails 不能使用预先加载的数据。相反,您可以创建一个新的关联:
has_many :active_variants, -> { where(is_active: true).order(:price) }, class_name: "Variant"
然后预加载并使用此关联而不是变体关联。