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

Bla*_*man 2 memcached ruby-on-rails

当我在控制器的操作中进行以下调用时,我可以看到我第一次加载页面时在控制台输出中看到输出“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
Run Code Online (Sandbox Code Playgroud)

如果我重新加载页面,我不会看到“posts hit the db”消息,但我仍然可以看到如下查询:

由 PostsController#index 处理为 HTML 渲染 posts/index.html.erb 内布局/主帖子加载(0.5ms) SELECT "posts".* FROM "posts" WHERE (post_status = 1) ORDER BY id desc ?app/views/posts/index.html.erb:6 标签加载 (0.3ms) SELECT "tags".* FROM "tags" WHERE "tags"."id" = $1 [["id", 7]] ? app/views/posts/index.html.erb:6 在布局/帖子中渲染的帖子/index.html.erb (31.4ms) 在 87ms 内完成 200 OK (Views: 62.6ms | ActiveRecord: 8.2ms)

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

例如,如果我删除视图页面中的所有 html,则它根本不会命中 db。

Bil*_*ble 5

当你做

Post.include(:tags).where("post_status = 1").order("id desc")
Run Code Online (Sandbox Code Playgroud)

您实际上并没有调用数据库。您正在创建一个 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
Run Code Online (Sandbox Code Playgroud)

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