片段缓存和渴望加载:如何充分利用这两个世界?

Kap*_*old 12 performance caching ruby-on-rails fragment-caching eager-loading

在我看来,片段缓存和急切加载 - 至少有时 - 在某种程度上相互矛盾.假设我有一个用户,他有很多帖子,每个帖子都有很多评论,反过来也可以有很多评论等等.

当我必须渲染页面时,我可以选择热切地加载用户,所有帖子,所有评论等等,以避免数据库n-1次.或者我可以懒惰地加载每个对象并依赖片段缓存来仅查询数据库中的新对象或已更改的对象.使用片段缓存和急切加载似乎都是浪费,因为我可能会做一个非常复杂的查询并实例化很多对象只是为了使用它们中的一小部分.

但是,如果我有一个应用程序,其中一个用户有许多Foos,而这些Foos又有很多Bars等等,但是其中每个Foo都是同时创建完整的所有Bars及其相关对象,从那时起就永远不会改变.在这种情况下,我想对已经渲染的Foos使用片段缓存,但是当我必须加载一个带有所有相关对象的新Foo时,要使用预先加载.毕竟,在更细粒度的级别缓存片段没有任何好处.

Rails实现这一目标的最佳方式是什么?我想我可以做一个查询来获取Foo的id,然后在我必须渲染每个Foo时用急切加载进行显式查找.这样做有更好/更优雅/更惯用的方式吗?

dav*_*idb 0

您可以使用fragment_exists?控制器中的方法来防止急切加载已在缓存中的所有对象。只有第一次调用该页面时才不会出现这种情况。

像这样:

  if fragment_exists? "my_cache_key_#{id}" 
    # load your object without eager loading here        
  else
    # eager load your objects here        
  end
Run Code Online (Sandbox Code Playgroud)

然后在视图中使用片段缓存:

<% cache("my_cache_key_#{@object.id}") do %>
...
...
...
<% end %>
Run Code Online (Sandbox Code Playgroud)

这应该适合你!