2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

includesでN + 1クエリ問題を対処する

Posted at

はじめに

先日、初めてN + 1クエリ問題に遭遇したため、その対処方法を記録します。
そもそも、N + 1クエリ問題とは?
...モデル同士が関連づけられているときに、レコードを全件取得しようとすると、SQLの発行回数が増えてしまい、動作が重くなる問題。
と認識している。間違っていたらごめんなさい。

N + 1クエリ問題が発生する実際の例

例えば、以下のような3つのモデルがあるとする。

product.rb
has_many :product_properties
has_many :properties, through: :product_properties
property.rb
has_many :product_properties
has_many :products, through: :product_properties
product_property.rb
belongs_to :product
belongs_to :property

コントローラー側では、親であるProductをidから検索し、取得する。

product_controller.rb
  def show
    @product = Product.find(params[:id])
  end

viewでは、関連先のデータを表示する。

show.html.erb
  <% @product.product_properties.each do |property| %>
    <%= #{property.value} %>
  <% end %>

このとき、N+1クエリ問題が発生している。

対処方法

コントローラを次のように変更する。

product_controller.rb
  def show
    @product = Spree::Product.includes(product_properties: :property).find(params[:id])
  end

こうすると、テーブルが結合されてSQLの発行回数が減る。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?