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わかりやすいプログラミング用語サイト