fv17の日記

Webエンジニアの備忘用ブログです。主にWeb界隈の技術に関して書いています。

N+1問題とは

N+1問題とは、必要以上にSQLクエリが発行され、その結果、速度低下に繋がりユーザビリティが悪くなる問題のこと。
N+1問題とか名前しらなかっただけで当たり前。

具体的には?

下記の記事を参照。
ruby-rails.hatenadiary.com

もしくは、Rails ガイドの「13 関連付けを一括読み込みする」に「N + 1クエリ問題」とズバリ。
railsguides.jp


どう解決するか?

includes、eager_load、preloadを使い

  • SQLの発行数を必要最低限に抑える
  • 取得したデータをキャッシュしておき、必要に応じて取り出す

下記の記事を参照。

qiita.com

英語が読める場合はこちらの方が具体例が多くて分かりやすい

blog.arkency.com

inner joinでeager loadingしたいはどうすれば?

ズバリの記事があった。
qiita.com

N+1問題にどう気づくか?

  • 実行時にコンソールのログに似たようなSQLが複数回発行されていたら要注意
  • Bullet gemを入れる (使いづらく感じるので微妙...)

なぜ何回もSQLを発行すると速度低下に繋がるのか?

こちらの書籍が詳しい。

SQL実践入門 ──高速でわかりやすいクエリの書き方
https://www.amazon.co.jp/dp/B07JHRL1D3/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

SQLが発行される時に内部で何が行われているかを説明してくれる。ただし、基本的なSQLを生で書けるレベルでないと読むのが難しいかも。

N+1を放置するとどれくらい遅くなるのか?

サンプルプログラムだとデータ数が数百かつ関連も少ないため、正直遅くないし、問題だと思わない。

しかし、本番プログラム、本番データになると数万、数十万とかの話になってくるので、性能の悪いPCやスマホだとカクカクして動かなくなる

マジでそんな遅くなるの?という場合は、ピクスタさんの記事
texta.pixta.jp