0
0

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 3 years have passed since last update.

N+1問題とその解決方法

Posted at

#目次
①N+1問題とは
②具体例
③解決方法

##①N+1問題とは
データベースからデータを取り出す際に、必要以上にSQLが発行され動作が悪くなってしまう問題のことをいう。

##②具体例
例えば、Userがcommentを投稿するwebアプリがあるとする。ここで、複数のUserが投稿したcommentを全権取得する場合、ユーザーのnickenameを表示させることをしたいケースを考える。

class CommentsController < ApplicationController
  def index 
   @comments = Comment.all
  end
end
#コメントを全件取得している

<% @comments.each do |comment| %>
 <%= comment %>
<small><%= comment.user.nickname %></small>
<%end%>
#一つ一つのコメントに対してのユーザーのニックネームを表示している

上記の流れを言語化すると
まず、コメントを全件取得している(DBに入っているデータを2件とする。)→1回
そして、それに紐ずくuserを1人取得する→2回
最後に、紐づいているuserを1人取得する。→3回

commentsテーブルに対して1回、userの人数分取得(今回は2回)なので計3回アクセスしていることになる。
これがN+1問題。もしこれが1000件になったら、その分DBにアクセスしなければならなくなる。

##③解決方法
結論としては、icludesメソッドを使う。
icludesメソッドにより、commentsに紐づいているuserを一気に取得できる。
仮にcommentが3つ取得できて、user_idがid=1,id=4,id=8とわかっている場合、usersテーブルから一気に持ってくることでこの問題は解決する。

class CommentsController < ApplicationController
  def index 
   @comments = Comment.includes(:user)
  end
#コメントを全件取得し,それに紐づくuserをDBから一気に取得している
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?