[Rails] includesとjoinsの違いを解説!

業務で、複数のmodelを参照してデータを取得する際にを使って、極力クエリを減らして

データを取得したい時に、includes joinsを使っているのですが、

ふと、「あれ、この2つの違いってなんやろ??」「includesjoinsはどうやって使い分けるんやろ」

て思ったので、備忘録のために記事書きました。

結論

まず結論から言います。

includes

別のmodelを参照しに行く際に、N+1問題を避けるために使う

joins

SQLでいう、INNER JOINをしたい時に使う

 

モデル構造

  • EndUser
  • EndUserAnswerAssociation
    • EndUserとAnswerの中間テーブル
  • Answer

EndUserとAnswerは多対多の関係

includes解説

まず、includesあり・なしで、どのようなクエリを叩くのか見ていきます。

includesなし

これでは、end_userレコード数が大量にある場合、クエリを叩きすぎてサービス低下しますね。。。

includesあり

answersをキャッシュしておく。
すると、以上のようなクエリを叩くだけですみます。

joins解説

joins は、modelを結合するだけで、キャッシュは行わないです。
なので、絞り込みを行い・参照側のmodelのデータを使わない場合は単体で使っても問題ないです。

正常に、INNER JOINされています。

 

さらにjoinsは、条件を指定して結合するレコードを絞り込むことができます。(以下参照)

しかし、この状態でAnswerのデータにアクセスすると、Answerをキャッシュしていないので、

アクセスした分クエリを叩くことになります。

includes joins組み合わせ

参照先のmodelのデータを使いたくて、絞り込みも行いた場合に組み合わせます。

 

 

まとめ

  • mapやeachなど、複数回、別のmodelを参照する際には、includes を使って参照先のmodelをキャッシュしておく。
  • inner joinして絞り込んで、さらにjoinしたmodelのデータを使わない時には、joins を使う。
  • 参照先のmodelのデータを使いたくて、絞り込みも行いた場合に includesjoinsを 組み合わせます。

 

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA