0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails】駆け出しエンジニア目線でN+1問題を解説します

Posted at

N+1問題とは

N+1問題とは、SQLが実行される際、クエリの回数が無駄に多くなってしまい、パフォーマンスを低下させてしまうことです。

※クエリとは、データベースからデータを抽出したり操作したりといった処理を行うための命令のことです。

つまり、必要なデータ(N)を抽出するごとに、毎度1回多く(+1)SQLが発行されてしまい、処理に時間がかかってしまいます。

というよりは、毎度必要なデータを抽出しにいく手間を無くすと考えた方がわかりやすいかもしれません。

なぜN+1問題を回避すべきなのか?

前述のとおり、パフォーマンスを低下させるからです。
また、大量のSQLが発行されることでコンピューターにも負担がかかります。

データ量が少なければあまり問題になりませんが数万、数十万とデータを抽出するとなると、高負荷になりパフォーマンスの低下につながることは容易に想像できるはずです。

いつまでたっても表示・更新されないWebサービスは嫌ですよね。私も嫌ですし、そもそもユーザーが離脱します。

具体例

ここでは、UserモデルとPostモデルが一対多の関係であるとします。
下記のコードでは、投稿した人の名前を表示しようとしています。

posts = Post.all

posts.each do |post|
  p  post.users.name
end

一見問題なさそうですが、これこそがまさにN+1問題が発生しているのです。
例えば投稿が100個あった場合、このコードだと101回SQLが発行していることになります。
ではこれを解決するにはどうすればよいのでしょうか?

N+1の解決策

解決策は一つではありませんが、もっとも簡単な方法としてはincludes メソッドを使用することです。

posts = Post.includes(:users).all

posts.each do |post|
  p  post.users.name
end

最初の一行目に.includes(:users)を追加しただけです。
こうすることで
N+1問題は、とくに一対多の関係で発生しやすいです。
他のテーブルからデータを取得するときにはとくに気をつけましょう。

まとめ

  • N+1問題とは、クエリの回数が無駄に多くなってしまい、パフォーマンスを低下させてしまうこと
  • とくに一対多の関係で発生することが多い
  • includes メソッドを使うことで解決できる

覚えてしまえばそんなに難しくないので、さくっと学習しておきましょう。

こちらの動画も参考になったのでおすすめです。
【Ruby on Rails】必ず知っておきたい N+1 問題(SQL)N+1 problem on Ruby on Rails


参考文献
Railsガイド~関連付けを一括読み込みする~

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?