Оптимизация запроса Rails 3.0, который возвращает сотни записей - PullRequest
3 голосов
/ 26 июня 2011

Среда: Rails 3.0.6 и MySQL

У меня есть следующие две модели:

class Employee < ActiveRecord::Base
  belongs_to :user
  belongs_to :manager
end

class Manager < ActiveRecord::Base
  has_many :employees
end

У меня есть страница, на которой для данного пользователя отображаются все сотрудники, находящиеся под ними все их прямые менеджеры.На этой странице обычно отображаются десятки записей, но для пользователей исполнительного уровня потенциально может отображаться до 1000 записей.(По разным причинам мы не хотим использовать разбиение на страницы.)

Метод контроллера, который отображает страницу, выглядит следующим образом (показан полностью)

def manage_reports

  @tab = "home"
  @sub = "manage"

  add_breadcrumb I18n.t("home_menu.My Reports"), :manage_reports_path

  @my_reports = current_user.employees.includes(:manager).order('manager.name)      

  respond_to do |format| 
    format.html
    format.pdf { render :layout => false } if params[:format] == 'pdf'
      prawnto :filename => "employee_list.pdf", :prawn => { }
  end  
end

Представление представляет собой простую таблицу, показывающуюстолбцы информации для сотрудника и два столбца информации для руководителя (имя и поле тега).Ни одна из двух моделей не имеет более десяти столбцов.Оба индексируются.

Время загрузки страницы варьируется от << 1 секунды до более 15 секунд в случае ~ 600 отчетов.После многих часов игры с индексами, объединениями и т. Д. Мы еще раз взглянули на разбивку производительности New Relic и обнаружили, что время, проведенное в контроллере, составляет 80% времени, тогда как запросы к БД фактически выполняются довольно быстро. </p>

У меня есть пара вопросов:

1) Что на самом деле происходит в контроллере, что занимает 80% времени?Это загрузка отчетов в память?Разве мы не должны ожидать, что сможем загрузить столько записей на страницу быстрее?

2) В таблице менеджера есть поле «био» с абзацем текста.Как исключить этот столбец при включении ассоциации менеджера?Документация по Rails 3.0.x выглядит особенно неоднозначной в этой теме.Нужно ли вообще исключать этот столбец?Если столбец био не доступен в представлении, загружается ли он когда-либо в память?Я запутался в том, загружаются ли ассоциации в Rails 3 в настоящее время или загружаются лениво.Если посмотреть на запрос в консоли, то только один запрос SQL загружает все столбцы для сотрудника и менеджера.

Обновление:

Это разбивка транзакции в NewRelic.(Извиняюсь за форматирование)

                          Time  Avg calls   Avg time (ms)  
* manage_employees          79  1           1,676  
* Manager#find              11  81          227  
* Tag#find                   9  82          185  
* Employee#find              1  2           19  
* Database SQL - SELECT     .3  1           5  
* User#find                 .1  1           3  

Код представления представляет собой простую таблицу.Каждая строка выглядит следующим образом:

<td align="left">  <%= link_to emp.mgr.name, show_mgr_path(emp.mgr) %></td>      
<td align="center"><%= emp.mgr.lang       %></td>       
<td align="center"><%= emp.num        %></td>   
<td align="center"><%= emp.status         %></td>           
<td align="center"><%= emp.test_score     %></td>
<td align="center"><%= emp.test_date      %></td>   
<td align="center"><%= emp.serviceyrs     %></td>
<td align="left">  <%= emp.tag_list.to_s  %></td>

1 Ответ

1 голос
/ 28 июня 2011

Читая ваш взгляд, я думаю, что я обнаружил потенциальную проблему:

<td align="left">  <%= emp.tag_list.to_s  %></td>

Кажется, ваш партиал выполняет другой запрос для получения списка тегов. Проверьте свои журналы - если это приблизительно, с 600 записями, это классическая проблема N + 1, которая объясняет ваше время ответа 15 секунд.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...