以下SQL查询会慢慢减慢我的网站极其!从0-1.5秒到轻松超过20秒。我该如何优化呢?
SELECT DATE(a.datetime_logged) AS date,
(SELECT COUNT(aa.data_status) FROM activity AS aa WHERE aa.id_user = '1' AND DATE(aa.datetime_logged) != CURDATE() AND DATE(a.datetime_logged) = DATE(aa.datetime_logged) AND aa.data_status = 'online') AS status_a,
(SELECT COUNT(aa.data_status) FROM activity AS aa WHERE aa.id_user = '1' AND DATE(aa.datetime_logged) != CURDATE() AND DATE(a.datetime_logged) = DATE(aa.datetime_logged) AND aa.data_status = 'idle') AS status_i,
(SELECT COUNT(aa.data_status) FROM activity AS aa WHERE aa.id_user = '1' AND DATE(aa.datetime_logged) != CURDATE() AND DATE(a.datetime_logged) = DATE(aa.datetime_logged) AND aa.data_status = 'streaming') AS status_s
FROM activity AS a
GROUP BY DATE(a.datetime_logged)
ORDER BY DATE(a.datetime_logged) DESC
LIMIT 40
这是表格:
CREATE TABLE IF NOT EXISTS `activity` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_user` int(11) NOT NULL,
`id_channel` varchar(50) NOT NULL,
`id_game` int(11) NOT NULL,
`data_muted_server` tinyint(4) NOT NULL,
`data_muted_self` tinyint(4) NOT NULL,
`data_deafen_server` tinyint(4) NOT NULL,
`data_deafen_self` tinyint(4) NOT NULL,
`data_suppressed` tinyint(4) NOT NULL,
`data_status` varchar(10) NOT NULL,
`data_game` text,
`datetime_logged` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `index_datelog` (`datetime_logged`)
)
答案 0 :(得分:1)
您可以使用sum(case data_status when 'online' then 1 end) as status_a
替换嵌套的重子查询
答案 1 :(得分:0)
你有这种形式的子查询:
SELECT COUNT(aa.data_status)
FROM activity AS aa
WHERE aa.id_user = '1'
AND DATE(aa.datetime_logged) != CURDATE()
AND DATE(a.datetime_logged) = DATE(aa.datetime_logged)
AND aa.data_status = 'online'
这些是令人讨厌的,特别是如果您的id_user
和data_status
列的基数很低。 DATE(aa.datetime_logged) != CURDATE()
术语使这些查询无法进行查询。
在(id_user, data_status, datetime_logged)
上尝试复合索引。这可能会有所帮助。
您也可以尝试
SELECT COUNT(aa.data_status)
FROM activity AS aa
WHERE aa.id_user = '1'
AND aa.datetime_logged >= DATE(aa.datetime_logged)
AND aa.datetime_logged < DATE(aa.datetime_logged) + INTERVAL 1 DAY
AND DATE(aa.datetime_logged) != CURDATE()
AND aa.data_status = 'online'
具有相同的复合指数。这将允许索引扫描。