使用对游戏结果的查询结果优化更新玩家得分表

时间:2012-06-26 08:19:40

标签: mysql optimization

我有一张包含所玩游戏结果的表格。我为每位球员提供另一张桌子,显示胜利,失败,平局。我想通过分析游戏表来更新玩家结果表。目前计算是在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 个答案:

答案 0 :(得分:1)

触发器可能是您的解决方案http://dev.mysql.com/doc/refman/5.0/en/triggers.html

如果gam_status是赢取更新+1以获得玩家的胜利,那么你将在temp_game_result中插入(或更新)一个有用的触发器......

将会(或多或少)

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;