2013-02-16 43 views
2

我正在編寫一個在線數學測試程序,並且正在編寫腳本來計算每個用戶的等級。下面的代碼有效,但每次我看到它時都會畏縮。基於結果表中的訂單更新行

get_set()將查詢的結果爲$用戶

function rank_users_in_test($tid){ 
    $GLOBALS['DB']->get_set($users,"select user,test from user_results where test=$tid order by points desc,time"); 
    // $users are already in order by rank thanks to ORDER BY 
    $rank = 1; 
    foreach ($users as $u){ 
    $GLOBALS['DB']->query("update user_results set world_rank=$rank where user={$u['user']} and test={$u['test']}"); 
    $rank++; 
    } 
} 

在循環中的查詢讓我哭了一下。我的問題是,有沒有一種方法可以讓MySQL根據它們在第一個查詢結果中出現的順序自動更新每個用戶的排名?有一個相關的問題here,但它不使用UPDATE。

我使用的MySQL 5.

+1

一個歸一化的數據庫的原理是,以不存儲計算值。我建議從user_results表中刪除列,並在需要時查詢現有數據。 – 2013-02-16 17:30:36

+0

我知道,但該網站在結果發佈的夜晚承受了非常大的流量。我們這樣做的結果只是查詢,但我們的服務器凍結 - 連接太多。當結果是靜態的,我們的服務器可以處理負載。但問題是比賽變得越來越大,而且這段代碼達到了我們的服務器允許的最大執行時間5分鐘(我無法改變這一點)。 – twentylemon 2013-02-16 17:34:36

+0

使用'auto_increment'等級字段創建一個臨時表,並且'insert into mytemp(userid,points ...)選擇用戶ID,測試點...按點排序desc ...'在一個查詢中擁有所有等級創建 – 2013-02-16 17:37:27

回答

0

由於上述的ring0,下面減少運行時間從幾分鐘到幾秒鐘:d

create table temp (
    rank int auto_increment, 
    user int, 
    test int, 
    primary key(rank) 
); 

insert into temp(user,test) (select user,test from user_results where test=$tid order by points desc,time); 

update user_results ur, temp t set ur.world_rank=t.rank where ur.user=t.user and ur.test=t.test; 

drop table temp; 
相關問題