2012-07-03 62 views
1

我正在研究一個迄今爲止擁有7000多行排行榜數據的項目,其中包含名稱,ID,分數和排名。它不斷擴大,我目前遇到了一個麻煩,在每次有人發佈新評分時嘗試更新所有內容後,服務器超時。用mySQL更新1000行的最有效方法?

目前我正在使用PDO查詢結合循環execute()調用。有沒有一個更快的方式來做到這一點(也許在一個單一的MySQL查詢)?或者,您對如何處理更新排行榜有任何建議嗎?

$stmt = $dbh->prepare("SELECT * FROM high_scores ORDER BY score DESC"); 
    $stmt->execute(); 

    $stmt->setFetchMode(PDO::FETCH_ASSOC); 
    $results = $stmt->fetchAll(); 

    // 

    $numItems = count($results); 

    // is this OK or a no-no? 

    try { 

     $stmt = $dbh->prepare("UPDATE high_scores SET rank = :rank WHERE uid = :uid"); 

     for($i=0; $i<$numItems; $i++){ 
      $rank = $i + 1; 
      $uid = $results[$i]['uid']; 
      $stmt->execute(array(':rank' => $rank, ':uid' => $uid)); 
     } 

     return true; 

    } catch (PDOException $e) { 
     echo($e->getMessage()); 
    } 

回答

1

爲什麼你需要存儲的排名?這是一種非規範化形式,您是否真的需要它,或者您是否實施了該步驟,因爲它預計需要?

例如見這個解決方案:

http://thinkdiff.net/mysql/how-to-get-rank-using-mysql-query/

也許嘗試如何執行?

另外,如果您看到他提供的示例,則可以在查詢中使用變量。這也將允許您將此更新語句合併到單個查詢中。一個循環中的查詢是一個很難的問題,不幸的是,它甚至不會真的很高效。

+0

這是一個很大的幫助,謝謝。 – maskedbacon

0

我認爲你可以做到這一切有一個查詢,像

UPDATE high_scores a SET rank = (SELECT count(uid) + 1 FROM high_scores b WHERE b.score > a.score) ORDER BY score DESC 

我沒有MySQL的使用權現在試試這個,不幸的是,如果事實證明這不是是可行的,我會刪除這個。

0

有一個mysql的'CASE'的快速谷歌。

您最有可能在這裏找到答案,但:Stackoverflow #9346755

本質上講,你有一個有它自己的「內部開關語句」一個SQL行。您只需告訴它在給定字段具有特定值時要執行的操作。例如。在上面的鏈接中,它的意思是......

When `id` is 1, then set the value to 12. 
When `id` is 2, then set the value to 42. 
etc. 

您唯一關心的可能是7000+行。

但是,使用PHP,我會有數據中的數據,然後使用array_slice(),一次獲取200/300條記錄,設置SQL行並執行。然後獲取下一個200/300條記錄並重復,直到達到PHP數組的末尾。

編輯: 請記住,只有當您基於另一個字段(如鍵)更新ONE字段時,上述內容纔有效。

相關問題