Как оптимизировать мой цикл подачи активности - PullRequest
2 голосов
/ 29 марта 2011

Я реализую ленту активности для своего приложения, очень похожую на ленту новостей Facebook. Всякий раз, когда пользователь что-то делает (создает сообщение, комментирует сообщение, создает фотоальбом, комментирует фотографию), в таблице «Действия» создается строка, содержащая идентификатор пользователя, категорию и данные. Данные - это сериализованный хэш, различный для каждого вида деятельности (сообщение содержит заголовок и идентификатор сообщения, комментарий к фотографии содержит что-то еще и т. Д.). Затем представление просматривает все действия и печатает что-то в зависимости от категории действия. Довольно просто, и это работает. Проблема в том, что это СУПЕР медленно, поэтому я, должно быть, делаю что-то не так. Вот код:

#activity.rb snippet

  def post?
   category == "post"
  end

  def post_comment?
   category == "post_comment"
  end

  def album?
   category == "album"
  end

  def photo_comment?
   category == "photo_comment"
  end

#controller snippet

@Activity = Activity.all(:order=> 'created_at DESC', :limit=>"5")

#view snippet

<% @Activity.each do |a| %>
 <div class="activity_item">
  <div class="avatar" style="background-image: url(<%= small_pic_url(a.user)%>) "></div>
  <div class="text"> <%= a.user.username %> 
  <% if a.post? %>
   posted <%= link_to a.data["post_title"], post_path(a.data["post_id"]) %>
  <% elsif a.post_comment? %>
   commented on <%= link_to a.data["post_title"], post_path(a.data["post_id"]) %>
  <% elsif a.album? %>
   created a <%= link_to "Photo Album", album_path(a.data["album_id"])%>
  <% elsif a.photo_comment? %>
   commented on <%= link_to "#{a.data["username"]}'s photo", upload_path(a.data["photo_id"])%>
  <% end %>
  </div>
 </div>
 <% end %>

Я добавил индекс user_id в таблицу активности, но это, похоже, мало что дало. Рендеринг 5 предметов / аватаров занятий занимает более 3 секунд, поэтому должен быть лучший способ справиться с этим.

1 Ответ

1 голос
/ 29 марта 2011

У вас есть индекс на created_at? Если вы этого не сделаете, это замедлит вас - MySQL должен будет прочитать каждую строку в вашей таблице действий, чтобы убедиться, что он получил последние пять (это применимо практически ко всему, используя предложение ORDER BY).

И еще пара предложений, но они незначительные. Можно сбрить несколько миллисекунд, но не более трех секунд:

  1. Включите пользователя при выборе вашей деятельности. Это позволит вам получать ваши действия и их пользователей в одном запросе БД. :include => :user должен сделать трюк, или есть метод Rails 3 в стиле .include(...), если вы предпочитаете.
  2. Я слышал, что сериализация может быть довольно медленной. Возможно, вы могли бы использовать полиморфную ассоциацию, а затем выбрать, что отображать, основываясь на a.whatever_type?

Надеюсь, это поможет!

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