Reputation: 1346
I have a ranking that every X time has a balance added to the total points of each player, changing how they are ranked. I want my rank to be calculated at DB (MySQL), but I want it to be efficient, so first things first, here's the BalanceIn code:
Q1:
UPDATE playerscore
SET points = points * 0.9 + GREATEST(-100, LEAST(100, balance)),
balance = 0;
Once the points
are updated for all them, I want to reorder the rank (only for ranked players), like so:
Q2:
SET @r = 0;
UPDATE playerscore p
INNER JOIN
(SELECT @r:=@r+1 as new_rank, player_id
FROM playerscore
WHERE is_ranked = 1
ORDER BY points DESC) s
ON p.player_id = s.player_id
SET p.rank = s.new_rank
WHERE is_ranked = 1;
It works, and solves my problem, but: is thisgoing to make 1 select, and from here update all values, or will it make a select for each playerscore row?
In pseudocode, that's what I DO NOT want:
foreach PlayerScore p in playescore
new = get_all_players_sorted
update p.rank = new.new_rank where p.player_id = new.player_id
endforeach
As it will be, for N players: N selects + N updates. I want it to be: 1 select + N updates (contained in a single update) like so:
new = get_all_players_sorted
foreach PlayerScore p in playescore
update p.rank = new.new_rank where p.player_id = new.player_id
endforeach
Am I doing it right with my query (Q2)??
Upvotes: 1
Views: 64
Reputation: 1270713
If this is your query, you can perhaps speed it up by rephrasing the query and using an index.
The index you want is playerscore(is_ranked, points desc)
. The query is:
SET @r = 0;
UPDATE playerscore p
SET p.rank = (@r := @r + 1)
WHERE is_ranked = 1
ORDER BY points desc;
In MySQL, you can use order by
with update
-- as long as you are not using a join
. In this case, you don't need a join
because you are setting the variable as a separate statement.
Upvotes: 1