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