MENU

Rails n+1 解消

n + 1については下記の記事を参考に

qiita.com

検証

  • model
Product
  belong_to product_price
ProductPrice
  has_many :products
  • view
    <% @products.each do |product| %>
    <tr>
      <td><%= product.title -%></td>
      <td><%= product.product_price.price -%></td>
    </tr>
    <% end %>

NGパターン

  • controller
  def index
    @products = Product.all
  • log

ProductPriceが2回のselectが投げられる

Product Load (1.2ms)  SELECT "products".* FROM "products"
ProductPrice Load (0.8ms)  SELECT  "product_prices".* FROM "product_prices" WHERE "product_prices"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
ProductPrice Load (0.8ms)  SELECT  "product_prices".* FROM "product_prices" WHERE "product_prices"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]

OKパターン

def index 
  @products = Product.preload(:product_price)

ProductPriceのselectは1回

 Product Load (0.5ms)  SELECT "products".* FROM "products"
ProductPrice Load (0.4ms)  SELECT "product_prices".* FROM "product_prices" WHERE "product_prices"."id" IN (1, 2)