【えぬぷらすわんもんだい】
N+1問題 とは?
最終更新:
💡 一覧1回に、行ごとの追加取得が積み重なる
一覧を取得する1回のクエリに加え、N件それぞれの関連データを取得するクエリが出て、合計N+1回になる問題。ORMの関連データの必要時取得や、ループ内の個別取得などで起きる。
📌 このページのポイント
N+1問題って具体的には?
記事3件の一覧と著者名を表示する例で考えよう。一覧を1回で取り、各記事の著者を別々のSQLで1回ずつ取得すると、1+3で4回になる。件数が増えるにつれて問い合わせも増え、通信や処理の負担が大きくなるんだ。
ORMなら必ずこうなるの?
どう減らせばいいの?
画面に必要な関連データをまとめて読む方法があるよ。Railsで著者の事前取得を指定すれば、記事と著者を別々のクエリで取得する。この単純な関連の例では、一覧1回と著者をまとめる1回の計2回になる。図もこの方法との比較だよ。
JOINすれば同じことになる?
一括取得に直せば確認は終わり?
必要な関連が全部読み込まれているか、不要なデータまで取っていないかも見るよ。SQLの回数だけでなく、取得行数や実行時間も変更前後で比べよう。複数の関連をたどる画面では、それぞれで追加取得が残っていないか確認するんだ。
まとめ:ざっくりこれだけ覚えればOK!
「N+1問題」って出てきたら「一覧を取った後、各件の関連データを個別に取りに行く問題」と思えばだいたいOK!
📖 おまけ:英語の意味
「N+1 Problem」 = N+1回の問題
💬 一覧取得の1回に、N件分の追加取得が重なるのでN+1だよ。対策で常に1回へ減らせるという意味ではないんだ。