開発環境ではcacheが効かないようになっているので有効にする。
config/environments/development.rb config.action_controller.perform_caching = true
例としてサービスマスタのModelを作成
mst_service.rb class MstService < ActiveRecord::Base end
controllerから以下のようなコードでcacheを利用
puts "cache_#{Rails.cache.read("mst_service").nil?}" mst_service = Rails.cache.fetch("mst_service",expires_in: 1.minutes) do mst = MstService.select(:service_id).where(:status => '0') mst end
4回アクセスした時の標準出力は以下のようになる。
2回目以降はキャッシュから取得できているようです。
cache_true cache_false cache_false cache_false
DBへのアクセスはこんな感じ。
アクセス回数分、DBにselectが投げられている。。。
MstService Load (0.3ms) SELECT `mst_services`.`service_id` FROM `mst_services` WHERE `mst_services`.`status` = '0' MstService Load (0.4ms) SELECT `mst_services`.`service_id` FROM `mst_services` WHERE `mst_services`.`status` = '0' MstService Load (0.2ms) SELECT `mst_services`.`service_id` FROM `mst_services` WHERE `mst_services`.`status` = '0' MstService Load (0.2ms) SELECT `mst_services`.`service_id` FROM `mst_services` WHERE `mst_services`.`status` = '0'
cacheには入っているようですが、DBへのアクセスが減っておらず、
やりたいことはDBへのアクセスを減らすことなので、意図したキャッシュの処理にはなっていません。
毎回SQLが発行されていることから、ActiveRecordの状態がキャッシュされていて、
データがキャッシュされる訳ではなさそうです。
DBから取得した内容をhashに入れてからキャッシュするように変えてみました。
puts "cache_#{Rails.cache.read("mst_service").nil?}" mst_service = Rails.cache.fetch("mst_service",expires_in: 1.minutes) do mst_data = MstService.select(:service_id).where(:status => '0') mst = {} mst_data.each do |data| mst.store(data.service_id,data.service_id) end mst end
4回アクセスした時の標準出力は以下のようになりました。
上のと内容は同じです。
cache_true cache_false cache_false cache_false
DBへのアクセスを確認したところ、以下のように1回だけに減っていました。
MstService Load (0.2ms) SELECT `mst_services`.`service_id` FROM `mst_services` WHERE `mst_services`.`status` = '0'
DBから取得した値をRails.cacheに入れるのであれば、ActiveRecordをそのまま入れるのではなく
hashに移し替えてから格納するのがよさそうですね。
0 件のコメント:
コメントを投稿