参考図書
リレーションで値を取り出すのは大変便利だが、そのまま使うとレコードの数が多い場合、DBへのアクセスに余計な負荷がかかっている。
前提
PersonモデルとBoardモデルがリレーションしている。
Personモデルには人のレコードが、Boardモデルには掲示板へのコメントがレコードされている。
余計な負荷とは
例えば、Person::allで全Personを取得する場合。まずPersonを全部取り出し、そこから一つ一つのPersonに関連付けられているBoardを取り出すというやり方をしている。
投稿されたBoardが10個あったとすると、Board全体を取得するのに1回、それから10個のBoardそれぞれで関連するPersonを取得するにに10回、計11回もデータベースに問い合わせをしている。
これは「N+1問題」と呼ばれている。
解決策
withメソッドを使う。
モデル::with(リレーション名)->get();
withメソッドを使うと、、、
- 1.Boardだけを取得する
- 2.得られたBoardのperson_idの値をまとめ、それからIDのPersonを取得する。
11回DBにアクセスしていたのが、2回で済む。