2
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 1 year has passed since last update.

includesを使ってSQLの発行件数を減らそう(N+1問題)

Last updated at Posted at 2022-02-24

SQLの発行件数が多いと指摘を受ける。

業務にて、ある一覧画面を作成していたところ、
自分が書いたソースをみた先輩から、
「この一覧画面のSQLの発行件数が多すぎる。ちょっと減らしてみて。」とご指摘を受けました。

SQLの発行件数が多いのはN+1問題が起きていたことが原因で、
includesを使用することで
事象を解決できたのでアウトプットしてみようと思います。

N+1問題とは

必要以上にSQLが実行されて、パフォーマンスが低下する問題。
今回指摘を受けた画面では、
ログを見ると、他のテーブルの情報を取得するため何度もSQLが発行されていました。

includesとは

includesメソッドは、関連している複数のテーブルからデータをあらかじめ取得するメソッドです。

N+1問題を解決させるためには、
都度SQLを発行させるのではなく、あらかじめデータをすべて取得しておくことで解決することができます。

例えば、
UserクラスとPostクラスがあって、
投稿からユーザ名を取得する処理があったとします。

# models/user.rb
class User < ApplicationRecord
  has_many :posts
end

# models/post.rb
class Post < ApplicationRecord
  belongs_to :user
end
# 投稿の一覧を取得する
posts = Post.all
posts.each do |post|
  p post.user.name
end

上記のメソッドを実行すると、
投稿の数だけSQL文が発行されてしまい、
効率が悪いです。

そこで、下記のようにincludesメソッドを使用して、
あらかじめ投稿に関するユーザ情報を最初にすべて取得します。
そうすることで、
投稿がいくらあってもSQLの発行を一度で済ますことが可能です。

# 投稿と、投稿に関連したユーザ情報を取得する。
posts = Post.includes(:user)

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

余談

※SQLの発行件数は画面に対してAlt+Pを押下したり、
 ログを見ることで確認できます。

参考記事:
https://techacademy.jp/magazine/22031
https://qiita.com/south37/items/b2c81932756d2cd84d7d

2
0
0

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
2
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?