WEBサービス創造記

WEBサービスを作ったり保守したりしてる人のメモブログです。

Active Record での Eager Loading

      2015/05/24

N + 1問題について

@user = User.all
<% @users.each do |user| -%>
  <%= user.blog.name %>
<% end -%>

上記のようにコントローラ側で取得した情報をビューで処理すると、usersテーブルに入っているレコードの総数 + 1回分のSQLが発行される。
例えばusersテーブルに100人分のレコードが登録されている場合は101回SQLが発生する(+1というのは最初にusers全件を取得するselect文を含めるから)。

このケースだとアソシエーション先のblogsテーブルの名前を取得するので、まず最初のselect文でusers全体を取得し、あとは取得した全レコードを走査してその関連先のブログ名を取得していくことになる。

このようなケースはN+1問題と呼ばれている。

Eager Loading

Eager Loadingはそのような非効率なクエリの発生を未然に防ぐ仕組みで、関連テーブルのレコードを予め読み込んでおく処理のことである。
ActiveRecordは:includeでEager Loadingを行うことができる。

@user = User.all(:include => :blogs)

これなら発行されるSQLが少なくなり、パフォーマンスはこちらのほうが高くなる。

参考資料

 - Ruby on Rails , ,