
例えば、友達の家を訪ねる時、友達の家の住所録から場所を調べ、さらに友達一人ひとりに「今、どこにいるの?」と電話するようなものです。本来1回の住所録確認で済むのに、友達の数だけ電話する無駄が発生します。データベースで同じようなことが起こり、処理が遅くなるのがN+1問題です。
面接官:N+1問題について説明してください。
私:N+1問題とは、ORM(Object-Relational Mapper)などを利用した際に発生しやすい、データベースへの不要なクエリ発行によるパフォーマンス低下のことです。
例えば、ブログ記事の一覧を表示する際、記事データと同時に著者情報も表示する必要があるとします。最初に記事一覧を取得するクエリ(1回)を実行し、その後、取得した各記事に対して著者の情報を取得するクエリを記事数分(N回)実行してしまうのが典型的なN+1問題です。
以前のプロジェクトでECサイトの商品詳細ページ表示処理において、このN+1問題が発生していました。商品の基本情報、在庫情報、レビュー情報をそれぞれ別のクエリで取得していたため、商品数が増えるほどレスポンスが悪化していました。
そこで、結合(JOIN)クエリを使用して1回のクエリで必要な情報を全て取得するように修正しました。また、ORMの設定を見直し、遅延ロードを回避するように設定しました。これにより、商品詳細ページの表示速度が大幅に改善し、レスポンスタイムが平均50%短縮されました。
現役エンジニアによる深掘り解説
メリット
結合クエリなどを利用することで、必要な情報を一度に取得できるため、データベースへのアクセス回数を減らすことができます。これにより、ネットワーク負荷やデータベースサーバーの負荷を軽減し、アプリケーション全体のパフォーマンスを向上させることができます。
ORMの設定(Eager Loadingなど)を適切に行うことで、N+1問題を回避し、効率的なデータ取得を実現できます。
デメリット
結合クエリが複雑になりすぎると、クエリの実行計画が悪化し、逆にパフォーマンスが低下する可能性があります。
ORMの設定によっては、意図せずN+1問題が発生してしまうことがあるため、注意が必要です。
遅延ロードは、一見すると初期ロード時間を短縮できる利点があるように見えますが、N+1問題を誘発する可能性があります。
⚠️ 面接突破のワンポイント
- N+1問題の説明と、それをどのように検知・特定するかを具体的に説明できるように準備しましょう。(例:Slow Query Logの分析、APMツールでのボトルネック特定など)
- 実際にN+1問題を解決した経験を、具体的な数値を用いて説明できるようにしておきましょう。(例:〇〇という処理でN+1問題が発生し、〇〇という対策を行った結果、レスポンスタイムが〇〇%改善した、など)


