我目前正在攻击一个事件站点,并且从来没有遇到过优化查询/扩展我的数据库的问题,因为从来没有那么多的数据,但现在数据库中有近百万行,而且需要大约15,000行m / s用于呈现事件的提要,特别是部分(在每个_event.html.erb中)非常慢的部分是显示您当前关注的所有用户的事件。我已经查找了很多提高性能的可能性,包括急切加载,索引,内存缓存等等......但是想知道如何重写它以便更快地执行?谢谢!
_attending.html.erb
<% if user_signed_in? %>
<% @rsvp = Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going') %>
<% if @rsvp.count == 0 %>
<%= eventcount(event) %> going.
<% elsif @rsvp.count == 1 %>
<% if eventcount(event) - 1 == 0 %>
<% Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going')[0..0].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %> is going.
<% end %>
<% else %>
<% Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going')[0..0].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %> and <%= eventcount(event) - 1 %> going.
<% end %>
<% end %>
<% elsif @rsvp.count == 2 %>
<% if eventcount(event) - 2 == 0 %>
<% Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going')[0..0].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %> and
<% end %>
<% Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going')[1..1].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %> are going.
<% end %>
<% else %>
<% Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going')[0..0].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %>,
<% end %>
<% Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going')[1..1].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %> and <%= eventcount(event) - 2 %> going.
<% end %>
<% end %>
<% elsif @rsvp.count == 3 %>
<% if eventcount(event) - 3 == 0 %>
<% Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going')[0..0].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %>,
<% end %>
<% Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going')[1..1].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %>, and
<% end %>
<% Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going')[2..2].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %> are going.
<% end %>
<% else %>
<% Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going')[0..0].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %>,
<% end %>
<% Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going')[1..1].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %>,
<% end %>
<% Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going')[2..2].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %> and <%= eventcount(event) - 3 %> are going.
<% end %>
<% end %>
<% end %>
<% else %>
<%= eventcount(event) %> going.
<% end %>
RSVP架构
create_table "rsvps", :force => true do |t|
t.string "status"
t.integer "event_id"
t.integer "voter_id"
t.string "voter_name"
t.string "voter_type"
t.timestamp "created_at", :null => false
t.timestamp "updated_at", :null => false
end
add_index "rsvps", ["voter_id", "voter_type", "event_id"], :name => "fk_one_rsvp_per_user_per_entity", :unique => true
add_index "rsvps", ["voter_id", "voter_type"], :name => "index_rsvps_on_voter_id_and_voter_type"
关系模式
create_table "relationships", :force => true do |t|
t.integer "follower_id"
t.integer "followed_id"
t.timestamp "created_at", :null => false
t.timestamp "updated_at", :null => false
end
add_index "relationships", ["followed_id"], :name => "index_relationships_on_followed_id"
add_index "relationships", ["follower_id"], :name => "index_relationships_on_follower_id"
用户模型的相关部分
has_many :relationships, :foreign_key => "follower_id",
:dependent => :destroy
has_many :following, :through => :relationships, :source => :followed
has_many :reverse_relationships, :foreign_key => "followed_id",
:class_name => "Relationship",
:dependent => :destroy
has_many :followers, :through => :reverse_relationships, :source => :follower
答案 0 :(得分:0)
如果大型数据库是RSVP:
你在部分中对数据库进行了非常大的调用,只尝试减少n次调用Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going')
,然后在不同的情况下进行处理。这可以对性能有所帮助(如果你有一个大的数据库,每次在大型数据库中调用.where都是一个复杂的过程)。重用变量@rsvp。
答案 1 :(得分:0)
只需快速清理并遵循@damoiser所说的你应该将你的观点重构为这样的东西。
<强> _attending.html.erb 强>
<% if user_signed_in? %>
<% @rsvp = get_rsvps %>
<% if @rsvp.count == 0 %>
<%= eventcount(event) %> going.
<% elsif @rsvp.count == 1 %>
<% if eventcount(event) - 1 == 0 %>
<% @rsvp[0..0].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %> is going.
<% end %>
<% else %>
<% @rsvp[0..0].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %> and <%= eventcount(event) - 1 %> going.
<% end %>
<% end %>
<% elsif @rsvp.count == 2 %>
<% if eventcount(event) - 2 == 0 %>
<% @rsvp[0..0].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %> and
<% end %>
<% @rsvp[1..1].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %> are going.
<% end %>
<% else %>
<% @rsvp[0..0].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %>,
<% end %>
<% @rsvp[1..1].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %> and <%= eventcount(event) - 2 %> going.
<% end %>
<% end %>
<% elsif @rsvp.count == 3 %>
<% if eventcount(event) - 3 == 0 %>
<% @rsvp[0..0].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %>,
<% end %>
<% @rsvp[1..1].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %>, and
<% end %>
<% @rsvp[2..2].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %> are going.
<% end %>
<% else %>
<% @rsvp[0..0].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %>,
<% end %>
<% @rsvp[1..1].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %>,
<% end %>
<% @rsvp[2..2].each do |f| %>
<%= link_to User.find(f.voter_id).name, User.find(f.voter_id).slug %> and <%= eventcount(event) - 3 %> are going.
<% end %>
<% end %>
<% end %>
<% else %>
<%= eventcount(event) %> going.
<% end %>
你也应该有这样的帮手:
<强> some_helper.rb 强>
module SomeHelper
def get_rsvps
Rsvp.where(:voter_id => current_user.following, :event_id => event.id, :status => 'going')
end
end
巨大注意: 这段代码仍然没有任何好处。我仍然认为有很多重构要做。就像link_to帮助器上的[0..0] .each和[1..1] .each和很多代码重复一样。但这样可以获得一些性能,因为你只是在调用rsvps并重用你在@rsvp中存储的内容。