Представление индекса загружается очень медленно - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть модель Schools и модель PerformanceStats.

PerformanceStat 
belongs_to :school

School
has_one :performance_stat

На индексной странице PerformanceStat отображаются все 2000 показателей производительности, а также school.name, school.score и school.city, иМне нужен доступ к school.id и school.slug.

Контроллер:

def index
   @performance_stats=PerformanceStat.all
end

Мой код просмотра:

 <tbody>
 <% @performance_stats.each do |stat| %>
   <% school = School.find(stat.school_id)%>
    <tr>
      <td><%= link_to school.name, school_path(city: school.city.parameterize.truncate(80, omission: ''), slug: school.slug) %></td>
     <td><%= number_with_precision(school.score, precision: 2)%></td>

, затем представление переходит к отображению статистики производительности.

Этот просмотр загрузкиочень медленно .... 10-20 секунд.Как я могу ускорить процесс?Я пробовал PerformanceStats.scoped, собирал школьную статистику и выбирал из массива, но, похоже, это не помогло.Могу ли я получить доступ к школьным атрибутам, не найдя школу для каждого PerformanceStat?Я считаю, что School.find немного замедляет ход событий.

У меня есть индексы: school_id в PerformanceStat и: score,: slug в модели School.

ОБНОВЛЕНИЕ:

Предложение в выбранном ответе добавить кешпривел к этой строке кода в действии индекса SchoolsController:

fresh_when etag: @performance_stats

Время загрузки сократилось до 18 мс.Это решение прекрасно работает для меня, потому что содержание действия индекса не меняется часто.Эти данные обновляются раз в год. Эта ссылка содержит другие предлагаемые решения для кэширования данных, которые часто изменяются.

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Довольно много вещей здесь. Прежде всего измените ваш метод контроллера на этот, иначе вы столкнетесь с n + 1 запросами

def index
 @performance_stats=PerformanceStat.includes(:school)
end

Так как вы с нетерпением загрузили школу, теперь вы можете получить к ней доступ прямо в виде:

<% stat.school %>

Во-вторых, загрузка почти 2000 записей за один раз не оптимальна, загрузка всех записей займет некоторое время. Для этого вы должны добавить нумерацию страниц, используя следующие гемы

0 голосов
/ 06 сентября 2018

PerformanceStat.all - сложный запрос, если у вас много данных в этой таблице, и он найдет школу для каждого performance stat. Из вашего кода я могу понять, что вы столкнулись с (N + 1) проблемой здесь.

ПРИМЕЧАНИЕ : вы не должны запускать запросы от ваших представлений или помощников и позволять контроллеру выполнять все действия.

Например, в вашем коде:

<% @performance_stats.each do |stat| %>
   <% school = School.find(stat.school_id)%> <- #THIS IS WRONG & LET THE ASSOCIATIONS DO ALL THE ACTION ON ITS OWN
     <tr>
       <td><%= link_to school.name, school_path(city: school.city.parameterize.truncate(80, omission: ''), slug: school.slug) %></td>
       <td><%= number_with_precision(school.score, precision: 2)%></td>

вы можете использовать includes, PerformanceStat.includes(:school), он выберет все школы для каждого PerformanceStat.

код вашего контроллера должен быть:

@performance_stats = PerformanceStat.includes(:school)

вместо: @performance_stats = PerformanceStat.all

и ваш код просмотра теперь будет:

<% @performance_stats.each do |stat| %>
   <% school = stat.school %> #make sure all stats have a school assigned to them otherwise you can put a check below whether the school is nil or not
     <tr>
       <td><%= link_to school.name, school_path(city: school.city.parameterize.truncate(80, omission: ''), slug: school.slug) %></td>
       <td><%= number_with_precision(school.score, precision: 2)%></td>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...