优化日期组的mysql查询
这是我的桌子:优化日期组的mysql查询,mysql,optimization,indexing,Mysql,Optimization,Indexing,这是我的桌子: CREATE TABLE IF NOT EXISTS `test_dates` ( `date` date NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `test_log` ( `id` int(10) unsigned NOT NULL, `timest` datetime NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf
CREATE TABLE IF NOT EXISTS `test_dates` (
`date` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `test_log` (
`id` int(10) unsigned NOT NULL,
`timest` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `test_dates`
ADD PRIMARY KEY (`date`);
ALTER TABLE `test_log`
ADD PRIMARY KEY (`id`),
ADD KEY `emissione` (`timest`);
我使用此查询来计算每个日期的日志数:
SELECT d.date, COUNT(l.id)
FROM test_dates d
LEFT JOIN test_log l ON l.timest>=d.date AND l.timest<d.date + INTERVAL 1 DAY
GROUP BY d.date
为什么mysql不能使用表索引
日志表大约有100000行,查询速度非常慢。尝试将其作为相关子查询运行:
SELECT d.date,
(SELECT COUNT(l.id)
FROM log l
WHERE l.timest >= d.date AND l.timest < d.date + INTERVAL 1 DAY
) as cnt
FROM dates d;
MySQL在使用带有GROUP BY的索引时不是很好。有时,使用子查询可以显著提高性能。您的表具有正确的索引。如果索引和相关子查询对您不起作用,更好的选择可能是更新日期表并添加摘要计数列。然后,当您在日志表中执行insert操作时,将1添加到日期表中有关日期的计数器中。如果还不存在这样的记录,请添加一条,并将其计数设置为1,因为它是一条新记录
然后,您需要做的就是根据日期范围从日期表中选择一个总和,而不要查看细节。一旦为可能的审查选择了一个给定的日期,您就可以查询基础数据。将其转过来。首先对第二个表执行有效分组,请参见下面的子查询,然后填写缺少的天数外部查询:
SELECT date,
IFNULL(log.ct, 0) AS ct
FROM
( SELECT DATE(timest) AS date,
COUNT(*) AS ct
FROM test_log
GROUP BY date
) AS log
RIGHT JOIN test_dates AS d USING(date);
如果要限制日期范围,请在子查询和外部查询中都添加WHERE子句。可能查询速度较慢?至少,关于查询性能的问题需要为所有相关表创建语句,最好也为样本数据,以及解释的结果。工作测试MySQL 5.6.26:没有区别。在家测试10.0.19:巨大的差异。也许MySQL 5.7和MariaDB 10一样好。我确认我用MySQL 5.6.26测试了它
SELECT date,
IFNULL(log.ct, 0) AS ct
FROM
( SELECT DATE(timest) AS date,
COUNT(*) AS ct
FROM test_log
GROUP BY date
) AS log
RIGHT JOIN test_dates AS d USING(date);