はじめに
Youtubeでrailsの学習動画を探していたら、この動画に出会いました!
railsを用いて、N+1問題について解説している動画です。
自分なりに理解できたのでrailsを用いて自分も簡単に説明してみます!
N+1問題とは?
これは「DBから無駄に大量のクエリを発行してしまう」ことでパフォーマンスが低下する問題です。
N+1 問題のイメージ
例えば ユーザーと投稿 の関係(User has_many :posts)を考えて見ましょう
# コントローラ
@users = User.all
# ビュー
<% @users.each do |user| %>
<%= user.name %>
<%= user.posts.first.title %> ここで posts を参照
<% end %>
この場合、発行されるSQLは
SELECT * FROM users; ユーザー一覧を取得
SELECT * FROM posts WHERE user_id = 1 LIMIT 1; 各ユーザーごとに投稿を取得(ユーザー数が N 人なら N 回)
SELECT * FROM posts WHERE user_id = 2 LIMIT 1;
・・・
これらの結果として、合計 N+1 回のクエリが実行されてしまいます。
ユーザーが 100 人いたら 101 回クエリが走ってかなり非効率ですね。
解決方法
Rails では includes を使って関連を事前に読み込むことで解決できます!
@users = User.includes(:posts)
これによりクエリは以下のように最適化されます。
SELECT * FROM users; ユーザー一覧を取得
SELECT * FROM posts WHERE user_id IN (1, 2, 3, ...); 関連する投稿をまとめて取得
2クエリで済みましたね!
まとめ
・N+1 問題とはDBから大量のクエリを発行してしまうこと
・結果として N+1 回のクエリ が発行され、パフォーマンス低下を招く
・Rails では includes を使って関連を事前取得するのが基本的な対策です
終わりに
以上N+1問題について簡潔にまとめてみました!
もし内容に誤りや補足があれば、ぜひコメントで教えていただけると嬉しいです。
自分自身まだ学習中なので、フィードバックをもとに記事も改善していきます。