为什么加载这么慢?有没有什么技术可以让它更快?

时间:2013-07-17 07:44:09

标签: ruby-on-rails ruby-on-rails-3

我正在使用名为“Mailboxer”的宝石(https://github.com/ging/mailboxer
这使Rails应用程序中的消息传递系统成为可能。

有了这个宝石,我每个页面都会显示10条收到的消息 我在这里使用Kaminari进行分页。

但是,我的代码有点太慢了。 它一次发出超过25个sql :( 我怎样才能让它更快?仅显示1页需要超过1500毫秒。

这是我的代码 这有什么问题?有没有什么技术可以让它更快?

控制器

@number_of_messages_to_display = 10
@messages = current_user.mailbox.inbox.page(params[:page]).per(@number_of_messages_to_display)
@messages_count = current_user.mailbox.inbox.count

查看(消息/ index.html.erb)

<%= @messages_count.to_s %> messages in your received message box.

<table>
    <% @messages.each do |m| %>
        <tr>
            <td><%= check_box_tag "id[]",m.id %></td>
            <td><%= if m.is_read?(current_user) then "Read" else "Un-read" %></td>
            <td><%= profile_link(m.recipients.first) if m.recipients.first != current_user %></td>
            <td><%= link_to m.subject, show_messages_path(:id => m) %></td>
            <td><%= today_datetime(m.last_message.created_at) %></td>
        </tr>
    <% end %>
</table>

查看(助手/ application_helper.rb)

def profile_link(user)
    if user
        nickname = user.user_profile.try(:nickname) 
        username = user.try(:username)
        link_to nickname,  show_user_path(username)
    else
        "Un-known"
    end
end

def today_datetime(date_time)
  date_time.to_date == Date.current.to_date ? "<span class='text-info'>#{date_time.to_s(:us)}</span>".html_safe : date_time.to_s(:us)
end

的routes.rb

get 'messages/:id' => 'messages#show', :as => :show_messages
get "users/:id" => 'users#show', :as => :show_user

模型/ user.rb

def to_param
  "#{username}"
end

1 个答案:

答案 0 :(得分:0)

N + 1 problem.

的经典示例

您检索@messages = current_user.mailbox.inbox.page,它将从messages表中检索记录。

在视图中,您循环遍历它们并检查每条消息的recipients列表( a has_many关系,可能基于receipts表,看到here)。因此,对于每条消息,您最终都会向数据库发送另一个查询。

您可以通过检索收件人以及邮件(以及last_message关联来解决此问题,因为您正在使用它):

@messages = current_user.mailbox.inbox.
    includes(:receipt, :last_message).page

此外,您可能会遇到另外一个问题,因为25个查询应该可以在现代计算机上快速执行。我建议使用类似RailsPanel工具的东西来追踪花费的时间。