优化用于统计的SQL子查询

时间:2015-09-04 09:35:27

标签: mysql sql bigdata

我为用户PC创建了一个简单的统计工具。它每5分钟记录一次我们所有PC的状态。一点前端给了我一个使用图表: enter image description here

现在随着数据的增长,SQL查询变得越来越慢,我正在寻找一种优化它的方法。

这是结构。如您所见,表“usage”包含大约600万条记录,它使用MySQL InnoDB:

Stuff(0).CrapC = New Long(99) {}

以下查询大约需要7秒钟才能执行。它是将数据提供给屏幕截图的查询。

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;

我不知道如何优化它。我错过了什么吗?或者我需要重新组织结构?任何提示?

3 个答案:

答案 0 :(得分:2)

除了将time比较移动到where子句之外,您还可以完全摆脱子查询:

/* create pivot table */
SELECT `time`,
       SUM(state = 'LinuxTU') AS LinuxTU,
       SUM(state = 'LinuxExt') AS LinuxExt,
       SUM(state = 'View') AS View,
       SUM(state = 'Browser') AS Browser
FROM usage u
WHERE `time` > 1441271078 AND `time` < 1441357478
GROUP BY `time`
ORDER BY `time` ASC;

答案 1 :(得分:0)

我认为你的问题出在最后

GROUP BY `time`
ORDER BY `time` ASC

因为子索引你的索引消失了。所以,你应该找到一种方法来消除它。

您是否也可以选择使用编程语言进行一些处理?只需从外部选择中选择内部选择+不带和的变量,也可以添加顺序,然后用编程语言进行处理。

或者你必须在查询中写这个吗?

答案 2 :(得分:0)

我找到了瓶颈。问题是内部查询。 HAVING似乎比WHERE慢得多。所以我尝试了一些不同的查询,现在我得到了这个结果:

需要7秒:

false

需要0.1秒:

SELECT `time`, `state`, COUNT(`state`) statecount
FROM `usage` u
GROUP BY `time`, `state`
HAVING `time` > 1441271078 AND `time` < 1441357478

并给我相同的结果。前端现在要快得多。