N+1問題の対策
N+1問題とは?
データベースからデータを取り出す際に、大量のSQLが発行されて、動作が重くなる現象
具体的な内容
ユーザー(users)が掲示板(boards)を投稿できるサービスがあって、掲示板一覧を表示したい場合、コントローラではallメソッドを使い、boardsテーブルからデータを取得する。
この時、1回SQLが発行される。
次にビューで掲示板の一覧を表示するとき、ユーザーと掲示板がアソシエーションを組んでいて、掲示板を投稿した人のユーザー名も表示するようにする。
掲示板の情報はallメソッドで取得してきたが、投稿したユーザー名はusersテーブルから取得する必要がある。よって、eachメソッドとかで1つの掲示板のユーザー名を表示させるたびにusersテーブルからレコードから取得するSQLが自動で実行される。これがN個あればN回SQLが実行されるので、全てのboardsテーブルのレコードを取得する+N回SQLが実行されるのでN+1問題と呼ばれる
つまりこのN回が多くなればなるほどSQLを発行する回数が増えるので重くなる
対策
includesメソッドを使う
@boards = Board.all.includes(:user)
のようにモデル名.includes(:関連名)の記述することで、今回ならboardsテーブルからデータを取得するときに、関連するusersテーブルのデータも取得してくれる。これによって都度SQLを発行されることがなくなる!!
参考文献
Active Record クエリインターフェイス - Railsガイド
【Rails】N+1問題って何?原因と対処法を徹底解説! | Pikawaka - ピカ1わかりやすいプログラミング用語サイト