【いーがーろーでぃんぐ】

イーガーローディング とは?

💡 必要なデータをまとめて先取り、N+1問題の特効薬
📌 このページのポイント
N+1問題 vs イーガーローディング N+1問題(遅い) 1回目: SELECT * FROM posts 2回目: SELECT * FROM users WHERE id=1 3回目: SELECT * FROM users WHERE id=2 4回目: SELECT * FROM users WHERE id=3 …N件分繰り返し 合計 N+1 回のクエリ 100件なら101回! イーガーローディング(速い) 1回目: SELECT * FROM posts 2回目: SELECT * FROM users WHERE id IN(1,2,3…) 合計 2 回のクエリ 関連データを一括取得! 100件でもたった2回 ORMのeager load / includes / with で事前に関連を読み込む IN句でまとめて取得するため、クエリ数が激減する
N+1問題とイーガーローディングの比較
ひよこ ひよこ

イーガーローディングって何を積極的に読み込むの?

ペンギン先生 ペンギン先生

関連テーブルのデータだよ。たとえばブログ記事の一覧を取得するとき、各記事の著者情報もまとめて取得するのがイーガーローディングだよ

ひよこ ひよこ

まとめて取得しないとどうなるの?

ペンギン先生 ペンギン先生

記事が100件あったら、まず記事一覧で1回、各記事の著者取得で100回、合計101回のクエリが走る。これがN+1問題で、レスポンスが激遅になるんだ

ひよこ ひよこ

イーガーローディングだと何回になるの?

ペンギン先生 ペンギン先生

JOINなら1回、IN句を使う方式でも2回で済むよ。RailsならArticle.includes(:author).all、LaravelならArticle::with('author')->get() と書くだけで適用されるんだ

ひよこ ひよこ

全部イーガーにしちゃえばいいんじゃない?

ペンギン先生 ペンギン先生

使わないデータまで取得するとメモリの無駄になるし、JOINが増えるとクエリ自体が重くなる。RailsにはBulletというGemがあって、N+1が起きてる箇所や不要なイーガーローディングを自動検出してくれるから、開発中に入れておくと便利だよ

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「イーガーローディング」って出てきたら「関連データをまとめて先に読み込む手法」と思えればだいたいOK!
📖 おまけ:英語の意味
「Eager Loading」 = 積極的な読み込み
💬 Eager は「熱心な・積極的な」という意味で、先回りしてデータを読み込むイメージだよ
← 用語集にもどる