N+1のメモ
メソッド名 | 発行SQL | キャッシュの生成 | メモ |
---|---|---|---|
joins | LEFT INNER JOIN | 無 | 遅延フェッチを行う。 |
left_outer_joins | LEFT OUTER JOIN | 無 | 関連テーブルでの絞り込み |
eager_load | LEFT OUTER JOIN | 有 | LEFT OUTER JOIN でキャッシュする。1 回のクエリで行う。即時にフェッチされる。 |
preload | SELECT句をモデル毎に1回ずつ | 有 | キャッシュする。クエリは複数回に分かれる。即時にフェッチされる。(JOIN は行われない。) |
includes | LEFT OUTER JOINまたは、SELECT句をモデル毎に1回ずつ | 有 | where / joins / references / eagar_load と組み合わせた場合には、eagar_load と同じ動作を行い、それ以外の場合には preload を行う。 |
joins + preload | LEFT INNER JOIN | LEFT INNER JOIN を行う。クエリは複数回に分かれる。即時にフェッチされる。 | |
joins + eagar_load | LEFT INNER JOIN | LEFT INNER JOIN を行う。1 回のクエリで行う。即時にフェッチされる。 |
includesメソッドについて
includes
メソッドでは以下の条件に合致する場合にはeager_load
の挙動を、合致しない場合はpreload
の挙動を行います。
- 引数に指定した関連テーブルに対し
joins
メソッドを使用している場合 - 引数に指定した関連テーブルに対し
where
メソッドを使用している場合 - 引数に指定した関連テーブルに対し
references
メソッドを使用している場合
includes
メソッドは状況に応じてよしなに挙動を変えてくれる。
しかし、コードの意図が伝わりづらいので、できるだけeager_load
やpreload
を使うのが望ましいです。