2014-09-26 63 views
1

我有一個排名,每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:[email protected]+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; 

它的工作原理,解決了我的p但是:這是爲了讓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

如果這是您的查詢,您可以通過改寫查詢並使用索引來加速它。

你想要的索引是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,因爲您將該變量設置爲單獨的語句。

+0

真的很好,很快!用100k寄存器進行測試,並花費不到一秒鐘來完成'Q1' +'Q2' :) – 2014-09-26 11:07:26