从忙表运行报告并避免锁定这些表

时间:2012-03-13 15:35:07

标签: mysql optimization query-optimization

我有很多涉及大型数据集连接的报告。这些表每秒写入多次。我的cronjobs在最有影响的时间运行查询,但我仍然担心通过锁定表来损害性能。

这是他们今天要求的一个简单例子。它显示了RIIA报告的播放时间:

SELECT  
    date_format(p.`played`, '%Y-%m') as `month`,
    SUM(TIME_TO_SEC(s.`length`))/3600 as `playtime`
INTO OUTFILE "/tmp/120313_playtime.csv"
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'
FROM 
    `plays` p,
    `songs` s
GROUP BY `month`

如何构建它以避免在查询运行时为播放表写入无线电应用程序的问题?我应该创建临时表并复制实时表吗?

//每次请求编辑EXPLAIN输出

+----+-------------+-------+------+---------------+------+---------+------+---------+---------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows    | Extra                           |
+----+-------------+-------+------+---------------+------+---------+------+---------+---------------------------------+
|  1 | SIMPLE      | s     | ALL  | NULL          | NULL | NULL    | NULL |    3909 | Using temporary; Using filesort |
|  1 | SIMPLE      | p     | ALL  | NULL          | NULL | NULL    | NULL | 4040933 | Using join buffer               |
+----+-------------+-------+------+---------------+------+---------+------+---------+---------------------------------+

CREATE TABLE `plays` (
  `play_id` int(11) NOT NULL auto_increment,
  `song_id` int(11) NOT NULL,
  `played` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  PRIMARY KEY  (`play_id`)
) ENGINE=MyISAM AUTO_INCREMENT=4040992 DEFAULT CHARSET=latin1 COMMENT='play counts for songs' AUTO_INCREMENT=4040992 ;


CREATE TABLE `songs` (
  `id` int(11) NOT NULL auto_increment,
  `title` varchar(255) NOT NULL,
  `artist_id` int(11) NOT NULL,
  `length` time NOT NULL,
  `album_id` int(11) NOT NULL,
  `active` tinyint(4) NOT NULL,
  `tracknum` varchar(16) NOT NULL,
  `bitrate` varchar(32) NOT NULL,
  `date_created` datetime NOT NULL,
  `date_modified` timestamp NOT NULL default '0000-00-00 00:00:00' on update CURRENT_TIMESTAMP,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4136 DEFAULT CHARSET=latin1 AUTO_INCREMENT=4136 ;

1 个答案:

答案 0 :(得分:1)

只有两个直接的事情浮现在脑海中......一,在戏剧和歌曲之间没有“加入”会导致笛卡尔积。其次,添加一个WHERE子句,我希望“播放”列是日期/时间,因此您可以查询所有记录< NOW(),所以如果在查询运行时添加任何内容,它们将被排除。由于您似乎每月都在进行,因此您甚至可以创建一个单独的表,该表只是按月和年分组的每个“时间段”的运行总计,然后您不必担心超长查询。然后,您可以运行当前有问题的月份...仍然低于NOW()。