假设我正在显示所有用户的帖子,如下所示。
<% @users do |user| %>
<div><%= user.name %> : </div>
<% user.posts.each do |post| %>
<div><%= post.title %></div>
<% end %>
<% end %>
在控制器中预先加载帖子(特别是数据库速度)是否更好?
@users = User.includes(:posts)
或者只是获取用户并在视图中加载帖子更好吗?
@users = User.all
答案 0 :(得分:0)
当您遍历集合并访问子关联时,这会创建所谓的N + 1查询问题,其中每条记录将创建一个单独的数据库查询。
如果单个请求最终使用100个数据库查询,您的服务器将立即停止运行。
<% @users do |user| %>
<div><%= user.name %> : </div>
<!-- This line will create a N+1 query -->
<% user.posts.each do |post| %>
<div><%= post.title %></div>
<% end %>
<% end %>
所以是的 - 预加载关联是构建可扩展(甚至工作)的应用程序所必需的。 ActiveRecord provides several methods such as .includes
, .preload
, .eager_load
, .join
和.left_outer_joins
(Rails 5)各自给出不同的结果,并且适用于不同的用例。