我正在查看用于查询帖子的sql查询,即使它正在缓存数据

时间:2018-09-22 19:36:51

标签: ruby-on-rails memcached

当我在控制器的操作中进行以下调用时,我可以看到第一次加载该页面时,我在控制台输出中看到了输出“ posts hit the db”。

cache_key = "posts"
@posts = Rails.cache.fetch(cache_key, expires_in: 5.minutes) do
  puts "posts hitting the db"
  Post.include(:tags).where("post_status = 1").order("id desc")
end

如果我重新加载页面,则看不到“帖子击中数据库”的消息,但仍然可以看到类似的查询:

  

由PostsController#index作为HTML渲染处理   布局内的posts / index.html.erb /主发布后加载时间(0.5ms)SELECT   “ posts”。*从“ posts”位置(post_status = 1)按ID desc排序   app / views / posts / index.html.erb:6标签加载(0.3ms)选择“标签”。*   在“标签”中的“标签”。“ id” = $ 1 [[“ id”,7]]↳   app / views / posts / index.html.erb:6呈现的帖子/index.html.erb   布局/帖子内(31.4ms)在87ms内完成200 OK(查看:62.6ms)   | ActiveRecord:8.2毫秒)

这是因为它正在缓存@posts,但是由于实际上并未使用@posts对象,所以甚至没有进行db调用?那么,当查看页面执行@ posts.each时,它将命中数据库吗?

例如,如果我在视图页面中删除了所有html,那么它根本不会打入数据库。

2 个答案:

答案 0 :(得分:3)

这样做的时候

Post.include(:tags).where("post_status = 1").order("id desc")

您实际上并不是在调用数据库。您正在创建ActiveRecord范围-这就是您要缓存的内容。如果要缓存数据库调用的结果,则需要执行以下操作:

cache_key = "posts"
@posts = Rails.cache.fetch(cache_key, expires_in: 5.minutes) do
  puts "posts hitting the db"
  Post.include(:tags).where("post_status = 1").order("id desc").all.to_a
end

相反,这使ActiveRecord实际上用表数据填充@posts。

答案 1 :(得分:1)

正如@bkimble所说,您需要添加.all才能将查询转换为数据库调用。但是,由于Rails 4,.all是延迟执行的。正如我在此Memcache guide for Rails中所解释的那样,您需要强制执行它,例如,通过添加.to_a来将结果转换为数组。

您的代码将如下所示:

cache_key = "posts"
@posts = Rails.cache.fetch(cache_key, expires_in: 5.minutes) do
  puts "posts hitting the db"
  Post.include(:tags).where("post_status = 1").order("id desc").all.to_a
end