我爲我們的用戶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