🐈

N+1問題について

1 min read

誤りがあったら指摘していただきたいです。

N*+1クエリとは

  • SQL発行の無駄のこと。

user.rb
class User < ApplicationRecord
  has_one :address
end
address.rb
class Address < ApplicationRecord
  belongs_to :user
end

上のような2つのモデルがあったとする。

- User.all.each do |user|
  = user.address.city

その時、このようなコードを書くとN+1問題が起こる。
最初にuserを取得する処理があった後、ユーザーの数だけaddressにアクセスしていることで無駄が生まれているのである。

解決方法

- User.includes(:address).all.each do |user|
  = user.address.city

こんな感じのコードに修正する。
こうすると、関連するモデルから最初にデータを持ってきてくれるため、いちいちaddressのデータが発行されない。
preload,eager_loadでも同様に解決できる。
これらのメソッドの違いは関連モデルのデータをどのようなクエリで取得するか。
preloadは複数回、eager_loadは1回、includesはそれらをいい感じに使い分けてくれる?(不安)らしい。

Discussion

ログインするとコメントできます