IT-Q

「N+1 問題」とは、何が起きている状態のことですか。

一覧を取るクエリ1本に加えて、ループの中で各行のリレーションを引くクエリがN本発行される状態です。合計 1+N 本になる仕組みと、Eloquent でこれが見えにくい理由を説明します。

面接官が見ているのは面談で前提として使われる最重要用語。知らないと深掘りの入口に立てない。

よくある答えと、面談でどう見られるか

  • 一覧を取る1本に加えて、各行ごとに1本ずつクエリが飛び、合計 1+N 本になっている
    これが N+1 です。件数に比例してクエリが増えるので、10件では気づかず数千件で落ちます。
  • 1本のクエリが遅く、実行に N 秒かかっている
    それは「遅いクエリ」の話で、N+1 とは別問題です。
  • 同じレコードを N 回重複して登録してしまっている
    データの重複とは無関係です。N+1 は読み取り時のクエリ本数の問題です。
  • N 個のテーブルを JOIN しすぎて結合が重くなっている
    JOIN のしすぎも問題になりますが、別の話です。

模範解答

一覧を取るクエリが1本、そのあとループの中で各行のリレーションを引くクエリがN本、合わせて 1+N 本発行される状態です。

  $posts = Post::all();          // 1本
  foreach ($posts as $post) {
      echo $post->user->name;    // 1件ごとに1本 → N本
  }

投稿が100件なら101本になります。エラーは出ず、ただ遅くなるだけなので、開発環境の10件では気づかず本番で問題化するのが厄介な点です。