这是我第一次尝试在StackOverflow上寻求帮助:)
我有下表:
CREATE TABLE `tinfinite_visits` (
`visit_id` int(255) NOT NULL AUTO_INCREMENT,
`identity_id` int(255) NOT NULL,
`ip` varchar(39) NOT NULL,
`loggedin` enum('0','1') NOT NULL DEFAULT '0',
`url` longtext NOT NULL,
`realurl` longtext NOT NULL,
`referrer` longtext NOT NULL,
`method` enum('GET','POST','HEAD','OPTIONS','PUT','DELETE','TRACE','CONNECT','PATCH') NOT NULL,
`client` longtext NOT NULL,
`referring` longtext NOT NULL,
`timestart` datetime NOT NULL,
`timeend` datetime NOT NULL,
PRIMARY KEY (`visit_id`),
KEY `timestart` (`timestart`),
KEY `identity_id` (`identity_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
在某些时候,我需要从此表中获取一些数据以生成折线图。我目前使用5个不同的查询,5个不同的时间间隔(总计,年,月,周,日)。
该表目前有大约200,000行,但会有更多(甚至数千万条记录)。
虽然我的查询完全符合此目的,但我正试图找到一种更好的表现方式。
所以我非常感谢有关如何提高查询性能的任何提示/建议,如果可能的话,最好将所有5个查询合并为1。
我正在使用的查询,它们的EXPLAIN以及它们的执行时间(大约200,000行)如下:
日查询:
SELECT COUNT(DISTINCT(`identity_id`)) AS visits, DATE_FORMAT(CONVERT_TZ(timestart, '-5:00', '+3:00'), '%l%p') AS unit
FROM tinfinite_visits
WHERE `timestart` >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
GROUP BY unit
ORDER BY `timestart` ASC
说明:
+----+-------------+----------------------+-------+---------------+-----------+---------+-----+-------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+-------+---------------+-----------+---------+-----+-------+------------------------------+
| 1 | SIMPLE | tinfinite_visits | range | timestart | timestart | 8 | | 11113 | Using where; Using temporary |
+----+-------------+----------------------+-------+---------------+-----------+---------+-----+-------+------------------------------+
时间:0.011280059814453
周查询:
SELECT COUNT(DISTINCT(`identity_id`)) AS visits, DATE_FORMAT(CONVERT_TZ(timestart, '-5:00', '+3:00'), '%a') AS unit
FROM tinfinite_visits
WHERE `timestart` >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY unit
ORDER BY `timestart` ASC
说明:
+----+-------------+------------------+------+---------------+-----+---------+-----+--------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+------+---------------+-----+---------+-----+--------+----------------------------------------------+
| 1 | SIMPLE | tinfinite_visits | ALL | timestart | | | | 205897 | Using where; Using temporary; Using filesort |
+----+-------------+------------------+------+---------------+-----+---------+-----+--------+----------------------------------------------+
时间:0.13543295860291
月份查询:
SELECT COUNT(DISTINCT(`identity_id`)) AS visits, DATE_FORMAT(CONVERT_TZ(timestart, '-5:00', '+3:00'), '%d') AS unit
FROM tinfinite_visits
WHERE `timestart` >= DATE_SUB(NOW(), INTERVAL 28 DAY)
GROUP BY unit
ORDER BY `timestart` ASC
说明:
+----+-------------+------------------+------+---------------+-----+---------+-----+--------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+------+---------------+-----+---------+-----+--------+----------------------------------------------+
| 1 | SIMPLE | tinfinite_visits | ALL | timestart | | | | 205897 | Using where; Using temporary; Using filesort |
+----+-------------+------------------+------+---------------+-----+---------+-----+--------+----------------------------------------------+
时间:0.21460795402527
年度查询:
SELECT COUNT(DISTINCT(`identity_id`)) AS visits, DATE_FORMAT(`timestart`, '%b') AS unit
FROM tinfinite_visits
WHERE `timestart` >= DATE_SUB(NOW(), INTERVAL 1 YEAR)
GROUP BY unit
ORDER BY `timestart` ASC
说明:
+----+-------------+------------------+------+---------------+-----+---------+-----+--------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+------+---------------+-----+---------+-----+--------+----------------------------------------------+
| 1 | SIMPLE | tinfinite_visits | ALL | timestart | | | | 205897 | Using where; Using temporary; Using filesort |
+----+-------------+------------------+------+---------------+-----+---------+-----+--------+----------------------------------------------+
时间:0.50977802276611
整体查询:
SELECT COUNT(DISTINCT(`identity_id`)) AS visits, DATE_FORMAT(`timestart`, '%b') AS unit
FROM tinfinite_visits
WHERE `timestart` >= DATE_SUB(NOW(), INTERVAL 100 YEAR)
GROUP BY unit
ORDER BY `timestart` ASC
说明:
+----+-------------+------------------+------+---------------+-----+---------+-----+--------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+------+---------------+-----+---------+-----+--------+----------------------------------------------+
| 1 | SIMPLE | tinfinite_visits | ALL | timestart | | | | 205897 | Using where; Using temporary; Using filesort |
+----+-------------+------------------+------+---------------+-----+---------+-----+--------+----------------------------------------------+
时间:0.52196192741394
非常非常感谢你!
答案 0 :(得分:1)
Salut Emilian,解释有时会随行数而变化。
但是,由于您在分组中使用计算列以及在哪里,您可以选择实现日期维度表。
您几乎可以找到任何数据库的日期维度表代码: