渲染视图时会自动“缓存”啥?
Posted
技术标签:
【中文标题】渲染视图时会自动“缓存”啥?【英文标题】:What is automatically "cached" when rendering a view?渲染视图时会自动“缓存”什么? 【发布时间】:2017-04-08 16:46:23 【问题描述】:假设我们在一个视图中有这两个输出:
@post.user.first_name
current_user.posts.size
如果上面的输出会在一个视图中被多次调用,Rails 是否“足够聪明”,不会每次都访问数据库?
如果答案是肯定的 - 是否有任何值得了解的“一般规则”?
如果答案是否定的 - 将关联的对象存储在它自己的变量中是否是一个好习惯?
【问题讨论】:
【参考方案1】:默认为 ActiveRecord caches queries for performance。如果您在控制台中执行 AC 查询几次,您会看到第二个查询由于 AC 缓存而执行得更快。所以我想这也适用于视图中的查询。
您可以使用 Rails Fragment Caching 功能手动缓存对象。
片段缓存允许将视图逻辑的片段包装在一个 缓存块并在下一个请求时从缓存存储中提供 进来。
还有Cache Stores供你使用。
Rails 为缓存数据提供了不同的存储方式(除了 SQL 和页面缓存)。
【讨论】:
【参考方案2】:对视图的查询是在呈现视图的控制器操作中完成的。您会注意到您在控制器操作中定义了@post
,但您可能看不到current_user
的定义。这通常是因为您使用的是设计 gem,而定义 current_user
方法的代码是 gem 的一部分。
渲染视图所需的一切都应在控制器中通过ActiveRecord
查询,并在应用程序的内存中查询,以准备渲染视图。因此多次调用 @post 或 current_user 应该无关紧要。
有时对象通过视图的关联被调用,例如。 @post.user.name
将不得不查询用户。这会起作用,但最好是模型-视图-控制器分离,以便将用户与控制器中的帖子一起预先加载。遵循 MVC 并确保您的查询发生在控制器中也将帮助您避免 N + 1 查询性能问题。见Rails Active Record Query Eager Load
使用帖子查询用户的示例。
@post = Post.find(post_params).includes(:user)
【讨论】:
感谢您的介绍。所以我的问题的答案可能是——不。 IE。 db 查询不会自动“缓存”,如果没有最佳实践(每个对象的实例变量和.includes
的用法) - 那么我们将更频繁地访问数据库。跨度>
是的,ActiveRecord 查询被缓存以提高性能,如果控制器操作中的查询相同,请参阅 Martin Zinovsky 的回答。但是,如果没有最佳实践,并且您开始在模板中请求关联的对象,您将强制执行额外的查询并损害性能。以上是关于渲染视图时会自动“缓存”啥?的主要内容,如果未能解决你的问题,请参考以下文章
使用计算的 aurelia 搜索过滤在渲染到视图时会导致问题