2011-03-12 48 views
0

所以我一直在研究IRC遊戲一年,現在用PHP編寫,並使用PHP到IRC框架。MySQL查詢優化

最近,我添加了歸檔分數的功能(它們每隔幾百次就會被重新設置),這迫使我更新各種管理功能。
我剛剛更新了一個函數,允許我合併兩個玩家(一些用戶不打擾他們的舊密碼等等),以便合併歸檔分數(如果在我找到之前發生了重置重複賬戶)。

比分,融合部(下圖)的作品已經打算,但我不知道是否是因爲我覺得很沉重,我可以優化工藝(但想不出更好的東西):

$from_stats = $this->db->query("SELECT `games`, `wins`, `points`, `date_archive` FROM ".$this->dbprefix."score WHERE `id`=".$id1." AND `channel`='".$gamechan."' GROUP BY `date_archive`"); // get scores for the original account 
$to_stats = $this->db->query("SELECT `games`, `wins`, `points`, `date_archive` FROM ".$this->dbprefix."score WHERE `id`=".$id2." AND `channel`='".$gamechan."' GROUP BY `date_archive`"); // get scores for the duplicated account 
$from_games = array(); 
$from_wins = array(); 
$from_points = array(); 
$from_date = array(); 
while (list($fromstats_games,$fromstats_wins,$fromstats_points,$fromstats_date) = $this->db->fetchRow($from_stats)) { // build score arrays for the original account 
    $from_games[count($from_games)] = $fromstats_games; 
    $from_wins[count($from_wins)] = $fromstats_wins; 
    $from_points[count($from_points)] = $fromstats_points; 
    $from_date[count($from_date)] = $fromstats_date; 
} 
$to_games = array(); 
$to_wins = array(); 
$to_points = array(); 
$to_date = array(); 
while (list($tostats_games,$tostats_wins,$tostats_points,$tostats_date) = $this->db->fetchRow($to_stats)) { // build score arrays for the duplicated account 
    $to_games[count($to_games)] = $tostats_games; 
    $to_wins[count($to_wins)] = $tostats_wins; 
    $to_points[count($to_points)] = $tostats_points; 
    $to_date[count($to_date)] = $tostats_date; 
} 
foreach ($from_date as $key1 => $id1_date) { 
    foreach ($to_date as $key2 => $id2_date) { 
     if ($id1_date == $id2_date) { // merge scores if dates match 
      $from_games[$key1] += $to_games[$key2]; 
      $from_wins[$key1] += $to_wins[$key2]; 
      $from_points[$key1] += $to_points[$key2]; 
      $this->db->query("UPDATE ".$this->dbprefix."score SET `games`=".$from_games[$key1].", `wins`=".$from_wins[$key1].", `points`=".$from_points[$key1]." WHERE `id`=".$id1." AND `channel`='".$gamechan."' AND `date_archive`='".$id1_date."'"); 
      break; 
     } 
    } 
} 
$this->db->query("DELETE FROM ".$this->dbprefix."score WHERE `id`=".$id2); // delete all entries for the duplicated account 

回答

0

只是一個提示:畢竟使用此查詢(如果你有合適的privilages)

$this->db->query("OPTIMIZE TABLE ".$this->dbprefix."score"); 

這應當引起所有索引此表被重新計算。你會注意到索引文件的大​​小已經改變爲1kb(或幾個字節)

+0

謝謝,會這樣做:) – shroom 2011-03-12 16:14:57

+0

多一件事,而不是DELETE FROM考慮使用TRUNCATE TABLE - 如果沒有觸發器應該是執行,這是一種比DELETE更快的方式 – 2011-03-12 16:19:51

+0

是的,我在其他情況下使用它,但在這裏我需要刪除選定的條目。 感謝您的投入:) – shroom 2011-03-12 16:34:13