2012-06-26 31 views
1

我有一張表格,其中包含玩過的遊戲結果。每個玩家都有另一張表格,顯示勝利,損失和抽獎。我想通過分析遊戲桌來更新玩家結果表。目前的計算是在PHP中完成的,由於遊戲數量的原因,我們的數據庫延遲了大約4秒,這會導致整體延遲。我正在考慮將操作轉移到存儲過程以使其更快。任何人都可以推薦一種聰明的方式來進行計算並對player_chan_stats進行後續更新。我想完全在mysql查詢中完成,因爲這可能比php更快(假設)。優化更新玩家成績表與遊戲結果查詢結果

這是我們的比賽結果表的提取物

CREATE TABLE IF NOT EXISTS `temp_game_result` (
    `gam_key` bigint(20) NOT NULL COMMENT 'the game key', 
    `gam_pla_1` bigint(20) NOT NULL COMMENT 'player 1', 
    `gam_pla_2` bigint(20) NOT NULL COMMENT 'player2', 
    `gam_to_play` tinyint(4) NOT NULL COMMENT 'who started', 
    `gam_start` datetime NOT NULL, 
    `gam_stop` datetime DEFAULT NULL, 
    `gam_status` enum('playing','win','draw','lose','error') NOT NULL COMMENT 'result with reference to gam_pla_1', 
    `mg_cleaned` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0 if it has not passed thru cleanup, 1 otherwise', 
    `chn_key` bigint(20) NOT NULL COMMENT 'the tournament the game was for', 
    PRIMARY KEY (`gam_key`), 
    KEY `gam_status` (`gam_status`), 
    KEY `gam_start` (`gam_start`), 
    KEY `gam_stop` (`gam_stop`), 
    KEY `mg_cleaned` (`mg_cleaned`), 
    KEY `gam_pla_1` (`gam_pla_1`), 
    KEY `gam_pla_2` (`gam_pla_2`), 
    KEY `chn_key` (`chn_key`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

INSERT INTO `temp_game_result` (`gam_key`, `gam_pla_1`, `gam_pla_2`, `gam_to_play`, `gam_start`, `gam_stop`, `gam_status`, `mg_cleaned`, `chn_key`) VALUES 
(1, 1, 2, 2, '2011-05-02 20:12:13', '2011-05-02 20:42:46', 'lose', 1, 1), 
(2, 1, 2, 1, '2011-05-02 20:43:00', '2011-05-02 21:55:19', 'error', 1, 1), 
(3, 2, 1, 1, '2011-05-03 21:13:18', '2011-05-03 21:14:21', 'win', 1, 1); 

這是我們的選手的結果表的提取物

CREATE TABLE IF NOT EXISTS `player_chan_stats` (
    `pcs_key` bigint(20) NOT NULL AUTO_INCREMENT, 
    `pla_key` bigint(20) NOT NULL, 
    `chn_key` bigint(20) NOT NULL, 
    `pcs_seed` int(11) NOT NULL, 
    `pcs_rank` int(11) NOT NULL, 
    `pcs_games` int(11) NOT NULL DEFAULT '0', 
    `pcs_wins` int(11) NOT NULL DEFAULT '0', 
    `pcs_losses` int(11) NOT NULL DEFAULT '0', 
    `pcs_draws` int(11) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`pcs_key`), 
    UNIQUE KEY `pla_key_2` (`pla_key`,`chn_key`), 
    KEY `pla_key` (`pla_key`), 
    KEY `pcs_seed` (`pcs_seed`), 
    KEY `pcs_rank` (`pcs_rank`), 
    KEY `chn_key` (`chn_key`), 
    KEY `pcs_wins` (`pcs_wins`), 
    KEY `pcs_losses` (`pcs_losses`), 
    KEY `pcs_draws` (`pcs_draws`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Stats of player per channel' AUTO_INCREMENT=26354 ; 

INSERT INTO `player_chan_stats` (`pcs_key`, `pla_key`, `chn_key`, `pcs_seed`, `pcs_rank`, `pcs_games`, `pcs_wins`, `pcs_losses`, `pcs_draws`) VALUES 
(1, 1, 1, 1552, 1844, 325, 146, 176, 3), 
(2, 2, 1, 1543, 2272, 93, 48, 43, 2); 

回答

1

觸發器可能是您的解決方案http://dev.mysql.com/doc/refman/5.0/en/triggers.html

一個有用的觸發你將在temp_game_result中插入(或更新)如果gam_status是贏得更新+1以贏得球員...

將有關觸發器(或多或少)

CREATE TRIGGER update_wins AFTER UPDATE ON account 
    FOR EACH ROW 
    BEGIN 
     IF NEW.gam_status = 'win' THEN 
      update player_chan_stats set pcs_wins=pcs_wins+1 where psc_key=NEW.gam_pla_1; 
      update player_chan_stats set pcs_losses=pcs_losses +1 where psc_key=NEW.gam_pla_2; 
     ELSEIF NEW.gam_status = 'lose' 
        [...] 
     END IF; 
    END; 
+0

感謝巴勃羅,我不知道,太偉大了!我會嘗試觸發器,看看他們是否工作。 – Isanderthul

+0

很高興有用:D –

+0

謹慎的說法:觸發代碼錯誤可能導致數據庫死亡和死鎖。 – Isanderthul