使用SELECT更新以创建排名(效率)

时间:2014-09-26 10:33:09

标签: mysql sql performance sqlperformance

我有一个排名,每个X时间都有一个余额添加到每个玩家的总分数,改变他们的排名方式。 我希望我的排名是在DB(MySQL)上计算的,但我希望它是高效的,所以首先要做的是,这里是BalanceIn代码:

Q1:

UPDATE     playerscore
SET        points = points * 0.9 + GREATEST(-100, LEAST(100, balance)),
           balance = 0;

一旦points为所有人更新,我想重新排序等级(仅限排名玩家),如下:

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;

它有效,并且解决了我的问题,但是:这是进行1选择,从这里更新所有值,还是会为每个玩家核心行选择?

在伪代码中,这就是我想要的东西:

foreach PlayerScore p in playescore
    new = get_all_players_sorted
    update p.rank = new.new_rank where p.player_id = new.player_id
endforeach

对于N个玩家:N选择+ N个更新。 我希望它是:1选择+ N更新(包含在单个更新中),如下所示:

new = get_all_players_sorted
foreach PlayerScore p in playescore
    update p.rank = new.new_rank where p.player_id = new.player_id
endforeach

我的查询是否正确(Q2)??

1 个答案:

答案 0 :(得分:1)

如果这是您的查询,您可以通过重新构造查询并使用索引来加快速度。

您想要的索引是playerscore(is_ranked, points desc)。查询是:

SET @r = 0;

UPDATE playerscore p
    SET p.rank = (@r := @r + 1)
    WHERE is_ranked = 1
    ORDER BY points desc;

在MySQL中,只要您没有使用order by,就可以将updatejoin一起使用。在这种情况下,您不需要join,因为您将变量设置为单独的语句。