我为我们的用户PC创建了一个简单的统计工具。它每5分钟记录我们所有电脑的状态。而一个前端给我一个用法图: 优化SQL子查询统计
现在随着数据越来越多,SQL查询越来越慢,我正在寻找一种方法来优化它。
这是结构。正如你所看到的,表“使用”载约6万条记录,并使用MySQL的InnoDB:
CREATE TABLE IF NOT EXISTS `usage` (
`id` int(11) unsigned NOT NULL,
`host_id` int(10) unsigned NOT NULL,
`time` int(10) unsigned NOT NULL,
`state` enum('LinuxTU','LinuxExt','View','Browser','Idle','Offline') CHARACTER SET latin1 NOT NULL DEFAULT 'Offline'
) ENGINE=InnoDB AUTO_INCREMENT=5963366 DEFAULT CHARSET=utf8;
ALTER TABLE `usage`
ADD PRIMARY KEY (`id`), ADD KEY `host_id` (`host_id`), ADD KEY `time` (`time`);
ALTER TABLE `usage`
MODIFY `id` int(11) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=5963366;
下面的查询需要大约7秒执行。这是将数据提供给屏幕截图的查询。
/* create pivot table */
SELECT `time`,
SUM(IF(state='LinuxTU', statecount, 0)) AS LinuxTU,
SUM(IF(state='LinuxExt', statecount, 0)) AS LinuxExt,
SUM(IF(state='View', statecount, 0)) AS View,
SUM(IF(state='Browser', statecount, 0)) AS Browser
FROM (
/* get data from last 24h grouped by state */
SELECT `time`, `state`, COUNT(`state`) statecount
FROM `usage` u
/* group by time to get every 5 minutes
group by state to get the state counter */
GROUP BY `time`, `state`
HAVING `time` > 1441271078 AND `time` < 1441357478
) AS s
GROUP BY `time`
ORDER BY `time` ASC
我不知道如何优化它。有什么我错过了吗?或者我需要重新组织结构?任何提示?
我可以通过改变从一个ENUM字段的表到多个国家领域消除支点查询(如LinuxTU = 0,LinuxExt = 1)。但是我认为多个领域使得它变得僵化和可能更为紧张(例如:LinuxTU = 1和LinuxExt = 1)。实际上前端使用这些数据。所以每个查询都会输出所需的数据。 – Michael