我正在建立一个系统来统计访问我的网站,然后将其显示在图表图表类型上。
例如,我希望通过以下方式获取所有访问次数:
- 今天的网络访客总数
醇>
SELECT COUNT(DISTINCT ip) FROM visits_website WHERE DATE_FORMAT(create_at, '%Y-%m-%d') = CURDATE()) AS total_today
- 网络总访问时间
醇>
SELECT COUNT(DISTINCT ip) FROM visits_website WHERE create_at >= DATE_SUB(NOW(), INTERVAL 1 HOUR)) AS total_before_hours
- 昨天的网站访问总数
醇>
SELECT COUNT(DISTINCT ip) FROM visits_website WHERE create_at >= DATE_SUB(NOW(), INTERVAL 1 DAY)) AS total_yesterday
- 本周访问网站总数
醇>
SELECT COUNT(DISTINCT ip) FROM visits_website WHERE YEARWEEK(create_at, 1) = YEARWEEK(CURDATE(), 1)) AS total_week
- 上周访问网站
醇>
SELECT COUNT(DISTINCT ip) FROM visits_website WHERE create_at >= DATE_SUB(NOW(), INTERVAL 1 WEEK)) AS total_last_weekend
- 总站点访问月数
醇>
SELECT COUNT(DISTINCT ip) FROM visits_website WHERE MONTH(create_at) = MONTH(NOW())) AS total_month
- 上个月访问网络总数
醇>
SELECT COUNT(DISTINCT ip) FROM visits_website WHERE create_at >= DATE_SUB(NOW(), INTERVAL 1 MONTH)) AS total_last_month
- 全年网络访问总数
醇>
SELECT COUNT(DISTINCT ip) FROM visits_website WHERE YEAR(create_at) = YEAR(CURDATE())) AS total_year
我正在MySql表中注册访问该网站,并且我希望在指定期间内使用不同IP收到此表所有访问的网页,我已经与MySql [DATE_SUB]函数进行了多次协商,因为不得不改变一些查询多次:
这些是我为所有访问所做的查询:
SELECT
COUNT(DISTINCT ip) AS total,
(SELECT COUNT(DISTINCT ip) FROM visits_website WHERE create_at >= DATE_SUB(NOW(), INTERVAL 1 HOUR)) AS total_before_hours,
(SELECT COUNT(DISTINCT ip) FROM visits_website WHERE DATE_FORMAT(create_at, '%Y-%m-%d') = CURDATE()) AS total_today,
(SELECT COUNT(DISTINCT ip) FROM visits_website WHERE create_at >= DATE_SUB(NOW(), INTERVAL 1 DAY)) AS total_yesterday,
(SELECT COUNT(DISTINCT ip) FROM visits_website WHERE YEARWEEK(`create_at`, 1) = YEARWEEK(CURDATE(), 1)) AS total_week,
(SELECT COUNT(DISTINCT ip) FROM visits_website WHERE create_at >= DATE_SUB(NOW(), INTERVAL 1 WEEK)) AS total_last_weekend,
(SELECT COUNT(DISTINCT ip) FROM visits_website WHERE MONTH(`create_at`) = MONTH(NOW())) AS total_month,
(SELECT COUNT(DISTINCT ip) FROM visits_website WHERE create_at >= DATE_SUB(NOW(), INTERVAL 1 MONTH)) AS total_last_month,
(SELECT COUNT(DISTINCT ip) FROM visits_website WHERE YEAR(`create_at`) = YEAR(CURDATE())) AS total_year
FROM visits_website
我想了解以下内容:
表格代码:
CREATE TABLE IF NOT EXISTS `visits_website` (
`id` BIGINT UNSIGNED AUTO_INCREMENT,
`ip` VARCHAR(25) NOT NULL,
`browser_short` VARCHAR(45) NOT NULL,
`browser_long` VARCHAR(255) NOT NULL,
`create_at` DATETIME NOT NULL,
PRIMARY KEY (`id`),
INDEX `FK_visits_website` (`ip`)
)Engine=InnoDB;
INSERT INTO `visits_website` VALUES ('1', 'ip1', 'ip1', '', '2016-08-31 20:30:00');
INSERT INTO `visits_website` VALUES ('2', 'ip1', 'ip1', '', '2016-08-31 20:30:00');
INSERT INTO `visits_website` VALUES ('3', 'ip2', 'ip2', '', '2016-08-31 19:30:00');
INSERT INTO `visits_website` VALUES ('4', 'ip1', 'ip1', '', '2016-08-31 19:30:00');
INSERT INTO `visits_website` VALUES ('5', 'ip2', 'ip2', '', '2016-08-31 18:30:00');
INSERT INTO `visits_website` VALUES ('6', 'ip3', 'ip3', '', '2016-08-31 18:30:00');
INSERT INTO `visits_website` VALUES ('7', 'ip1', 'ip1', '', '2016-08-31 17:30:00');
INSERT INTO `visits_website` VALUES ('8', 'ip2', 'ip2', '', '2016-08-31 17:30:00');
INSERT INTO `visits_website` VALUES ('9', 'ip3', 'ip3', '', '2016-08-31 16:30:00');
INSERT INTO `visits_website` VALUES ('10', 'ip4', 'ip4', '', '2016-08-31 16:30:00');
INSERT INTO `visits_website` VALUES ('11', 'ip1', 'ip1', '', '2016-08-30 20:30:00');
INSERT INTO `visits_website` VALUES ('12', 'ip2', 'ip2', '', '2016-08-30 20:30:00');
INSERT INTO `visits_website` VALUES ('13', 'ip3', 'ip3', '', '2016-08-30 20:30:00');
INSERT INTO `visits_website` VALUES ('14', 'ip4', 'ip4', '', '2016-08-30 20:30:00');
INSERT INTO `visits_website` VALUES ('15', 'ip5', 'ip5', '', '2016-08-30 20:30:00');
INSERT INTO `visits_website` VALUES ('16', 'ip1', 'ip1', '', '2016-08-30 20:30:00');
INSERT INTO `visits_website` VALUES ('17', 'ip2', 'ip2', '', '2016-08-30 20:30:00');
INSERT INTO `visits_website` VALUES ('18', 'ip3', 'ip3', '', '2016-08-30 20:30:00');
INSERT INTO `visits_website` VALUES ('19', 'ip4', 'ip4', '', '2016-08-30 20:30:00');
INSERT INTO `visits_website` VALUES ('20', 'ip5', 'ip5', '', '2016-08-30 20:30:00');
INSERT INTO `visits_website` VALUES ('21', 'ip6', 'ip6', '', '2016-08-29 20:30:00');
INSERT INTO `visits_website` VALUES ('22', 'ip1', 'ip1', '', '2016-08-29 20:30:00');
INSERT INTO `visits_website` VALUES ('23', 'ip2', 'ip2', '', '2016-08-29 20:30:00');
INSERT INTO `visits_website` VALUES ('24', 'ip3', 'ip3', '', '2016-08-29 20:30:00');
INSERT INTO `visits_website` VALUES ('25', 'ip4', 'ip4', '', '2016-08-29 20:30:00');
INSERT INTO `visits_website` VALUES ('26', 'ip5', 'ip5', '', '2016-08-29 20:30:00');
INSERT INTO `visits_website` VALUES ('27', 'ip6', 'ip6', '', '2016-08-29 20:30:00');
INSERT INTO `visits_website` VALUES ('28', 'ip7', 'ip7', '', '2016-08-29 20:30:00');
INSERT INTO `visits_website` VALUES ('29', 'ip1', 'ip1', '', '2016-08-29 20:30:00');
INSERT INTO `visits_website` VALUES ('30', 'ip2', 'ip2', '', '2016-08-29 20:30:00');
非常感谢您的帮助。
答案 0 :(得分:3)
这是一个很长的问题。关于这种基于DATETIME
的摘要生成的一个关键建议:Make your queries sargable -- make them able to use an index.
例如:
SELECT COUNT(DISTINCT ip)
FROM visits_website
WHERE MONTH(create_at) = MONTH(NOW() /* Slow! */
不是sargable,因为它将函数(MONTH()
)应用于表中的列。 MySQL必须检查表的每一行以满足此查询。这将是 slooooow 。而是试试这个,寻找本月的所有访问。
SELECT COUNT(DISTINCT ip)
FROM visits_website
WHERE create_at >= LAST_DAY(NOW()) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND create_at < LAST_DAY(NOW()) + INTERVAL 1 DAY
这是有效的,因为它会搜索从当月开始直到但不包括下月初的DATETIME
值范围。
然后,在(create_at, ip)
上创建compound covering index,您的查询应运行良好。 MySQL可以扫描它所需的索引范围。
请注意,这一切都适用于TIMESTAMP
数据。