mysql - 优化 SQL 子查询进行统计

标签 mysql sql bigdata

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

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

这是结构。正如你所看到的,表“usage”包含大约600万条记录,它使用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

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

最佳答案

除了将 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;

关于mysql - 优化 SQL 子查询进行统计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32394712/

相关文章:

python - 如何在 python mysql 中比较索引值与数据库值?

c# - 尝试通过我的本地主机作为后端和 c# 作为前端为我的 MySQL 数据库创建项目

mysql - 从案例陈述中选择

sql - 在 SQL Server 中将单列转换为多列

mysql - 索引sql查询

matlab - 从大 mat 文件中读取变量

php - 如何减少 php/mysql 数组选择循环中的查询

mysql - 使用批处理文件保存 MySQL 查询的问题

sql - 抛出太多行但只选择了一行

hadoop - 节俭安装./bootstrap配置错误的解释器