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

标签 mysql sql performance sqlperformance

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

问题 1:

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

一旦他们的points都更新了,我想重新排序排名(只针对排名玩家),像这样:

问题 2:

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)?

最佳答案

如果这是您的查询,您或许可以通过改写查询和使用索引来加快速度。

你想要的指数是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 byupdate 一起使用——只要您不使用 join。在这种情况下,您不需要 join,因为您将变量设置为单独的语句。

关于mysql - 使用 SELECT 更新以创建排名(效率),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26057534/

相关文章:

sql - MS-SQL 中是否有等效于 SHA1() 的方法?

sql-server - SQL Server 体系结构指南

MySql奇怪的性能

php - 在本地运行 Web 应用程序

mysql - SQL 查询以提取所有带有类别的 WordPress 帖子

mysql - 如何与实体经理一起加入 Doctrine ?

python - 如何在 sqlalchemy 查询中返回相关实体的计数

c++ - 为什么在 vector 中间添加或删除元素这么慢?

mysql - 将 SQL 查询字符串插入到 SQL 表中

javascript - 在 Sequelize 的 "where"子句中使用联结表中的列?