【概要】
1.結論
2.N+1問題とは何か
3.なぜN+1問題になるのか
4.N+1問題を解決する方法
1.結論
includesメソッドを使う!
2.N+1問題とは何か
アソシエーションをしている時に起こる問題です。
対策せずにアソシエーションを組むと
AデータベースとBデータベースが
一個一個全てを参照していくことをしてしまうため
処理が多くなってしまい動作が遅れてしまう問題です。
由来は、全てのレコードをまとめて1個+中身のレコードN個分ということでN+1となっています。
3.なぜN+1問題になるのか
例えば下記の例を見てみます。
class Student < ActiveRecord::Base
has_many :personals
end
class Personal < ActiveRecord::Base
belongs_to :student
end
Student_Tabel
id | student_name | student_age |
---|---|---|
1 | Ayabe | 15 |
2 | Sato | 16 |
3 | Ito | 14 |
Personal_Tabel
id | student_id | student_personality |
---|---|---|
1 | 1 | angry |
2 | 2 | gentle |
3 | 3 | smart |
4 | 1 | shy |
5 | 1 | forgetful |
この状態の時に、
@students = Student.all
とすると、StudentとPersonalを
モデルとデーターベースで1個ずつ照合した上で、
またコントローラーでビューに反映させる際に
同じことをしてしまいます。
この形ですと、(Studentsテーブル1回+データの参照回数15回)*2回
の処理を行ってしまうということですね!
4.N+1問題を解決する方法
この問題を解決してくれるのが、includesメソッドです!
モデルとデーターベースで1個ずつ照合してしまう部分をとりあえず関連されたモデルは全部持ってきて、コントローラーでビューに反映させる際に1個ずつ照合することができます。
2度同じことしなくて済むのでその分処理が軽くなります。
上記は少ないデーターなのでたいしたことはないですが、これが何千個何万個となると処理もその分違いが出てきます。
使用の仕方は
@students = Student.includes(:personal)
モデルの名前.includes(:紐づけたいモデルの名前)
のみです!