🐙

N+1問題

2021/07/10に公開

概要

DBアクセスが合計 N+1 回実行される問題

  1. SELECT を 1 回実行し、N レコードを取得
  2. 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

  1. SELECT を 1 回実行し、N レコードを取得
  2. Nレコードに関連するIDをリストにする。
  3. 関連IDリストを引数にしてSELECTを一回実行(Nレコードを取得)
GitHubで編集を提案

Discussion