🦧

AcctveRecord::Relationを利用してSQL発行回数を抑える方法

2021/04/21に公開

AcctveRecord::Relationとは?

ActiveRecord::Relationではデータベースへの問い合わせ結果ではなく、あくまで「どのようなSQLが発行されるか」という情報が保持されているに過ぎず、実際にSQLの実行結果が必要になるまではデータベースへのアクセスは実行されません。
これにより必要以上にデータベースとの通信が発生するのを抑えることが可能になります。

なお今回の内容には関係ありませんが、メソッドチェインを使用するためにもこの設計は必要不可欠です。
なぜならメソッドを呼び出した途端にSQLが実行されてしまう場合、まとめて全ての条件をメソッドに渡す必要があるためです。

SQLの発行回数を抑える実例


このようなモデルを例にします。
idが1のユーザーのお気に入り商品を取り出す場合、以下のような方法でSQL発行回数を抑えることが可能です。

 product_ids = Like.where(user_id: 1).select(:product_id)
 products = Product.where(id: product_ids)

where,selectメソッド共にAcctveRecord::Relationを返すクエリインターフェイスであり、一行目の時点ではデータベースへの問い合わせは行われていません。
二行目で初めてデータベースへと問い合わせが行われるのでSQLの発行を一回に抑えることができました。

もちろんrails tutorial
14.3.3 サブセレクト のようにSQL文で以下のように書くことも可能ですが、せっかく便利なAcctveRecord::Relationが利用できるにもかかわらずわざわざSQL文を書く必要はなさそうです。

 product_ids = "SELECT product_id FROM likes
                     WHERE user_id = 1"
 products = Product.where(id: product_ids)

参考

・パーフェクト Ruby on Rails
Active Record クエリインターフェイス
railsチュートリアル サブセレクトでなぜ高速化するのか

Discussion