Rails 4:我应该在控制器中预加载关系吗?

时间:2017-02-07 18:40:17

标签: ruby-on-rails database

假设我正在显示所有用户的帖子,如下所示。

<% @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

1 个答案:

答案 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)各自给出不同的结果,并且适用于不同的用例。