Railsのクエリキャッシュについて
仕組み
ActiveRecordはクエリキャッシュという機能がある
Partner.find(1)
という処理が走った時に
1. ActiveRecordがPartner.find(1)
をSELECT 'partners'.* FROM 'partners' WHERE 'partners'.'id' = 1
という SQLクエリに変換してDBに問い合わせる
1. DBから返ってきた情報を元にPartner
クラスのインスタンスを作成する
この処理の中でSQLクエリと実行結果をキャッシュに保存する 再度同じ処理をする時にキャッシュを使ったほうが、DBに再アクセスするよりも高速に行える
例
irb(main):011:0> user = User.where(id: 1) D, [2021-08-17T17:59:50.832891 #221] DEBUG -- : User Load (0.7ms) SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL AND `users`.`id` = 1 # この時にキャッシュされる irb(main):012:0> user.first.email => "example@example.com" # user id:1のemailを書き換え user.find(1).update!(email: "changed@example.com") # userを確認 irb(main):015:0> user => [#<User id: 1, email: "example@example.com", created_at: "2021-08-17 10:42:23.000000000 +0900", updated_at: "2021-08-17 17:59:36.000000000 +0900", deleted_at: nil>] # 最初のSQLのキャッシュが残っているため、DBの値が更新されていても値が変わっていない # reloadすると再度クエリが走るため値が変わる irb(main):016:0> user.reload D, [2021-08-17T18:03:12.599594 #221] DEBUG -- : User Load (0.7ms) SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL AND `users`.`id` = 1 => [#<User id: 1, email: "changed@example.com", created_at: "2021-08-17 10:42:23.000000000 +0900", updated_at: "2021-08-17 18:01:06.000000000 +0900", deleted_at: nil>]
注意
参考にしたサイト
Rails のクエリキャッシュの仕組みを調べた - takatoshiono's blog はじめに 〜SQLキャッシュにまつわる失敗〜|Ruby on Rails のSQLキャッシュ(書きかけ)