🦧
AcctveRecord::Relationを利用してSQL発行回数を抑える方法
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