2013-01-16 56 views
0

我在應用程序中實現了一個排行榜,我想每隔幾次更新一次。 對於我創造了排行榜的兩個表,每一個看起來是這樣的:用低成本CPU進行MySql更新

user_id, score, rank 

,這是我的更新查詢:

select score from leaderboard order by score for update; 
select(@rankCounter := 0); 
update leaderboard set rank = (select(@rankCounter := @rankCounter + 1)) order by score desc; 

我用我的活動表的查詢和每隔幾時間我切換活動表。

此更新目前需要3分鐘(在我的機器上)才能更新4M原始數據。 我希望減少所需的CPU數量,我不在乎更新會花費更長的時間。

我該怎麼做?

回答

0

我建議您嘗試添加索引... ON leaderboard (score),以避免排序操作。我也建議你從UPDATE語句中刪除不必要的SELECT語句(但是我不知道這是否會影響性能,但是在這種情況下SELECT關鍵字是不必要的。)

排序操作肯定會使用一些CPU,我不清楚優化器是否忽略了UPDATE語句中的SELECT,或者計劃是否與那些(不必要的)SELECT(在那裏)有什麼不同(在SELECT中包含SELECT關鍵字的目的是什麼? )

此外,沒有必要從每行返回得分值以獲得排行榜表中所有行的鎖定。該SELECT語句的ORDER BY也可能正在佔用CPU週期(如果存在與沒有索引3210作爲主要專欄。不必要的4M行結果集的準備工作也會佔用CPU週期。

目前尚不清楚爲什麼有必要在表中的所有行上獲取鎖,使用SELECT ... FOR UPDATE時,UPDATE語句本身將獲得必要的鎖。 (該SELECT ... FOR UPDATE語句只會在BEGIN TRANSACTION的情況下進行鎖定,或者自動提交被禁用。(我在這裏假設leaderboard是一個InnoDB表。)


MySQL可能能夠使用索引來避免排序操作:

CREATE INDEX leaderboard_IX1 ON leaderboard (score) ; 

,這應該是足夠的更新排名列:

SET @rankCounter := 0; 
UPDATE leaderboard 
    SET rank = @rankCounter := @rankCounter + 1 
ORDER BY score DESC ; 
+0

TNX幫我提高性能一點,但q問題是如何減少CPU,因爲時間幾乎沒有改變,所以它的CPU。 –