🐙
N+1問題
概要
DBアクセスが合計 N+1 回実行される問題
- SELECT を 1 回実行し、N レコードを取得
- Nレコードに関連するデータを取得するSELECT を N 回実行
抽象化コード
list_all = select_all() // Nレコード取得
for( row in list_all){
detail = select_detail(row.id) // N回DBアクセス
}
背景
↑の実装は馬鹿馬鹿しいが、ORMを使う場合に自動で発行されるクエリに発生しやすいそうだ。
対策
- JOIN句で結合する
- Eager loadingを使う
Eager loading
- SELECT を 1 回実行し、N レコードを取得
- Nレコードに関連するIDをリストにする。
- 関連IDリストを引数にしてSELECTを一回実行(Nレコードを取得)
Discussion