【问题标题】:Rails view rendering takes too long time with fetching child object in DBRails 视图渲染在 DB 中获取子对象需要很长时间
【发布时间】:2019-11-21 11:08:23
【问题描述】:

我的 rails 应用程序花了很长时间来渲染视图。此视图由子对象组成。

首先,我的“课程”对象属于“学校”

class Course < ApplicationRecord
    belongs_to :school
end
class School < ApplicationRecord
    has_many :courses, dependent: :destroy 
end

控制器。

class CoursesController < ApplicationController
    before_action :set_course , only: [:show, :edit, :update, :destroy]

    # GET /courses
    # GET /courses.json
    def index
       @courses = Course.all
    end

   // other stuffs..

end

在视图中,我有一部分用于在 DB 中呈现课程与学校的关系。

index.html.erb

<div>
    <table>
        <thead>
            //.....stuffss..
        </thead>
        <tbody>

            <% @courses.each do |course| %>
            <tr>
                <th><%= course.school.location %></th> // This parts are referencing 'school'..
                <td><%= course.school.name %></td>
                <td><%= course.name %></td>
                <td><%= convert_currency(course.price) %></td>
                <td><%= link_to "course", course_path(course.id), :class => 'button'  %></td>
                <td><%= course.school.nationalmix %></td>
                <td><%= course.school.certificate %></td>
                <td><%= course.school.good %></td>
                <td><%= course.school.bad %></td>
                <td><%= link_to "course", course_path(course.id), :class => 'button'  %> </td>
            </tr>
            <% end %>

        </tbody>
    </table>
</div>

原来渲染页面需要这么长时间。

Started GET "/courses" for ::1 at 2019-11-21 10:57:23 +0000
Processing by CoursesController#index as HTML
  Rendering courses/index.html.erb within layouts/application
  Course Load (0.3ms)  SELECT "courses".* FROM "courses"
  ↳ app/views/courses/index.html.erb:102
  School Load (0.2ms)  SELECT "schools".* FROM "schools" WHERE "schools"."id" = $1 LIMIT $2  [["id", 4], ["LIMIT", 1]]
  ↳ app/views/courses/index.html.erb:104
  School Load (0.2ms)  SELECT "schools".* FROM "schools" WHERE "schools"."id" = $1 LIMIT $2  [["id", 5], ["LIMIT", 1]]
  ↳ app/views/courses/index.html.erb:104
  School Load (0.4ms)  SELECT "schools".* FROM "schools" WHERE "schools"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ app/views/courses/index.html.erb:104
  CACHE School Load (0.0ms)  SELECT "schools".* FROM "schools" WHERE "schools"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ app/views/courses/index.html.erb:104
  School Load (0.3ms)  SELECT "schools".* FROM "schools" WHERE "schools"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
  ↳ app/views/courses/index.html.erb:104
  Rendered courses/index.html.erb within layouts/application (Duration: 7941.3ms | Allocations: 184810) // See this line.
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 6], ["LIMIT", 1]]
  ↳ app/views/layouts/application.html.erb:71
Completed 200 OK in 8015ms (Views: 8011.2ms | ActiveRecord: 1.8ms | Allocations: 205787)

在布局/应用程序中渲染课程/index.html.erb(持续时间:7941.3 毫秒 | 分配:184810)

差不多 8 秒。 有没有更好的方法呢?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord


    【解决方案1】:

    您需要急切地加载学校:

    @courses = Course.all.includes(:school)
    

    你可以在excellent blog post找到非常详细的描述

    【讨论】:

    • 我在博文中应用了这个和其他建议。但它并没有提高性能。
    • 您的日志中是否还有多个用于加载学校的 SQL 语句?
    • 也许您应该对结果进行分页,而不是在一个页面上显示所有结果?你有多少课程?
    • 我只能看到 1 条 SQL 语句。是的,没错。我还假设 convert_currency(course.price) 这个 API 调用主要导致了这个问题。
    • 是的,这就是问题所在。我用 Rails 缓存解决了这个问题。并感谢 eager_loading 方法。这显然以某种方式帮助了性能。 stackoverflow.com/a/30111615/4735043
    猜你喜欢
    • 1970-01-01
    • 2016-02-21
    • 1970-01-01
    • 2010-11-17
    • 2020-04-11
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多