Hi,
I have a application where i want to rank players according to the goals
they have scored. I can actually make the ranking work, but I have
performance problems when I try to fetch the total opponent score (goals
scored again an user in any match).
Basically what I do is call player in @players.find(:all) and apply the
action oppenent_total_score in the players model like this:
class Player < ActiveRecord::Base
has_many :participations, :class_name => “MatchParticipant”
has_many :matches, :through => :participations
def opponent_total_score(player)
@opponent_score = 0
matches.each do |score|
player_side = score.participants.find(:last, :conditions =>
[“player_id = ?”, player]).side
opponent_score = score.participants.find(:first, :limit => 10,
:conditions => [“side != ?”, player_side]).score
@opponent_score = @opponent_score + opponent_score
end
return @opponent_score
end
end
The problem arises as soon as there are more than 250 matches, where it
takes about 0,5 seconds to process the query.
With a database schema looking like this:
create_table “match_participants”, :force => true do |t|
t.integer “player_id”, :null => false
t.integer “match_id”, :null => false
t.string “side”, :null => false
t.integer “score”
t.boolean “winner”
end
create_table “matches”, :force => true do |t|
t.datetime “created_at”
t.datetime “updated_at”
end
create_table “players”, :force => true do |t|
t.string “name”
t.string “login”
t.string “password”
t.string “email”
t.datetime “created_at”
t.datetime “updated_at”
end
end
Where match_participant is a join table of players and matches in
has_many and belongs_to relations. One match can have either 2 or 4
participants.
How can i optimize this query to make it possible to search even more
matches without performance issues? The problem, as I see it, is that I
can’t do a clean SQL query, since I have to determine the player’s side
before I know what score I will have to sum (the opponent’s score).
Will I need to go for a different database structure in order to
archieve better performance? As this is obviously an very important
feature of a player ranking system I would like to make it as effective
as possible.
Thanks,
Rune