Mysql 我的SQL命令太长了,有没有简化?

Mysql 我的SQL命令太长了,有没有简化?,mysql,sql,performance,Mysql,Sql,Performance,我有一个包含以下列的表(播放器): playerID varchar(20) MMR int(10) RANK int(10) 目前有500k排 现在我想更新排名前10k球员的排名栏 因此,我创建了以下SQL命令 START TRANSACTION; UPDATE player SET player.RANK = 10001 WHERE player.Rank < 10001; SET @rank := 0; CREATE TEMPORARY TABLE IF NOT EXIS

我有一个包含以下列的表(播放器):

playerID varchar(20)
MMR int(10)
RANK int(10)
目前有500k排

现在我想更新排名前10k球员的排名栏

因此,我创建了以下SQL命令

START TRANSACTION;

UPDATE player 
SET player.RANK = 10001 
WHERE player.Rank < 10001;

SET @rank := 0;

CREATE TEMPORARY TABLE IF NOT EXISTS tmpRank AS (SELECT @rank := @rank + 1 AS rank, PlayerID, MMR
   FROM player ORDER BY MMR DESC LIMIT 10000);


UPDATE player, tmpRank 
SET player.RANK = tmprank.rank 
WHERE player.PlayerID = tmprank.PlayerID;

COMMIT;
指数

Schlüsselname   Typ     Unique  Gepackt Spalte      Kardinalität    Kollation   Null    
PRIMARY         BTREE   Ja      Nein    PlayerID    479032          A   Nein    
DeviceID        BTREE   Ja      Nein    DeviceID    479032          A   Nein    
Name            BTREE   Ja      Nein    Name        479032          A   Nein    
MMR             BTREE   Nein    Nein    MMR         9580            A   Nein    
RANK            BTREE   Nein    Nein    RANK        2               A   Nein
此SQL查询“应如何工作”:

  • 通过将每个玩家的等级设置为内部最大值+1(仅设置之前排名的玩家)来“降低等级”

  • 创建一个包含排名前10k球员的临时表

  • 根据临时表更新玩家表,必要时更改等级
编辑#2

UPDATE player 
SET player.RANK = 10001 
WHERE player.Rank < 10001;

仅此查询就需要此查询必然非常繁重

你会经常做这个更新吗?如果是这样,我认为在表中有大量更新的列是糟糕的设计。相反,将其放在另一个(“平行”)表中

这样做可能会加快查询速度。甚至可以使用id+rank创建一个表,然后
RENAME table
将其放置到位。这将基本上没有“停机时间”。是的,计算和构建仍然需要很长时间,但用户不会受到影响。我想这是你真正关心的


如果可能,可以动态计算值,而不是存储它。(我怀疑这是否可行,因为你称之为“排名”。

这个查询一定非常繁重

你会经常做这个更新吗?如果是这样,我认为在表中有大量更新的列是糟糕的设计。相反,将其放在另一个(“平行”)表中

这样做可能会加快查询速度。甚至可以使用id+rank创建一个表,然后
RENAME table
将其放置到位。这将基本上没有“停机时间”。是的,计算和构建仍然需要很长时间,但用户不会受到影响。我想这是你真正关心的


如果可能,可以动态计算值,而不是存储它。(我怀疑这是否可行,因为你称之为“排名”。

为什么只停留在前10k?另外,我不太确定我是否在做你声称的事情。对于查询优化建议,我们需要查看表的定义,包括所有列和所有索引。我同意@GordonLinoff。这似乎是在更新不在前10K中的玩家。假设代码按您所说的做,MMR上的索引将是尝试优化的一个良好开端,因为查询严重依赖于它。您好,感谢您的回答,我编辑了条目postWhy stop in the top 10K?另外,我不太确定我是否在做你声称的事情。对于查询优化建议,我们需要查看表的定义,包括所有列和所有索引。我同意@GordonLinoff。这似乎是在更新不在前10K的玩家。假设代码按您所说的做,MMR上的索引将是尝试优化的一个良好开端,因为查询非常依赖它。您好,谢谢您的回答,我编辑了条目postThank you,这似乎是最好的解决方案。我试过了,用不到3秒钟的时间就创建了一个拥有30万顶级玩家的新表:)谢谢,这似乎是最好的解决方案。我试过了,用不到3秒钟的时间就创建了一个拥有30万顶级玩家的新表:)
UPDATE player 
SET player.RANK = 10001 
WHERE player.Rank < 10001;
SET @rank := 0;
CREATE TEMPORARY TABLE IF NOT EXISTS tmpRank AS (SELECT @rank := @rank + 1 AS rank, PlayerID, MMR
   FROM player ORDER BY MMR DESC LIMIT 10000);
SET @rank := 0;
CREATE TEMPORARY TABLE IF NOT EXISTS tmpRank AS (SELECT @rank := @rank + 1 AS rank, PlayerID, MMR
   FROM player ORDER BY MMR DESC LIMIT 10000);


UPDATE player, tmpRank SET player.RANK = tmprank.rank WHERE player.PlayerID = tmprank.PlayerID;