php - Mysql - SQL 查询计数器每天、每月、每年和总计的 Web 访问量

标签 php mysql database

我正在制作一个系统来计算我网站的访问次数,然后将其显示在图表类型上。

例如,我希望通过以下方式获取所有访问:

  1. Total web visitors today

从visits_website WHERE DATE_FORMAT(create_at, '%Y-%m-%d') = CURDATE()) SELECT COUNT(DISTINCT ip) AStoday

  1. Total visits web for an hour

从 Visits_website WHERE create_at >= DATE_SUB(NOW(), INTERVAL 1 HOUR)) 中选择 COUNT(DISTINCT ip) AStotal_before_hours

  1. Total site visits yesterday

从 Visits_website WHERE create_at >= DATE_SUB(NOW(), INTERVAL 1 DAY)) AStotal_yesterday 中选择 COUNT(DISTINCT ip)

  1. Total visits site of the week

从 Visits_website WHERE YEARWEEK(create_at, 1) = YEARWEEK(CURDATE(), 1)) AS Total_week 中选择 COUNT(DISTINCT ip)

  1. Total visits website last week

从 Visits_website WHERE create_at >= DATE_SUB(NOW(), INTERVAL 1 WEEK)) AS Total_last_weekend 中选择 COUNT(DISTINCT ip)

  1. Total site visits Month

从 Visits_website WHERE MONTH(create_at) = MONTH(NOW())) AS Total_month 中选择 COUNT(DISTINCT ip)

  1. Total visits Web last month

从 Visits_website WHERE create_at >= DATE_SUB(NOW(), INTERVAL 1 MONTH)) 中选择 COUNT(DISTINCT ip) AStotal_last_month

  1. Total Web visits all year

从 Visits_website WHERE YEAR(create_at) = YEAR(CURDATE())) AS Total_year 中选择 COUNT(DISTINCT ip)

我正在一个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

我想知道以下内容:

  1. 这就是这些最佳的 mysql 查询以及制作这个系统的最佳方式吗?
  2. 这是一个很好的开发实践,表中需要更多索引。

表格代码:

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');

非常感谢您的帮助。

最佳答案

这是一个很长的问题。关于这种基于 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! */

不可控制,因为它将函数 (MONTH()) 应用于表中的列。 MySQL 必须检查表的每一行才能满足此查询。那将是。相反,请尝试此操作,查找当月的所有访问。

 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 值。

然后,创建一个 compound covering index(create_at, ip) 上,您的查询应该运行良好。 MySQL可以扫描它需要的索引范围。

请注意,这对于 TIMESTAMP 数据也同样适用。

关于php - Mysql - SQL 查询计数器每天、每月、每年和总计的 Web 访问量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39277032/

相关文章:

PHP - 从文本字段中获取文本以放入小部件

php - 如何将数据库中的信息插入我网站上的 php/display 中?

Mysql View 中的子查询非常慢

php - 值之间的差异 = "";且值= NULL;在 PHP 中?

增加innodb缓冲池后MySQL出错

java - 记录java应用程序的cpu使用情况

php - 将性别 'Male' 和 'Female' 存储为 Enum 类型好不好?数据库

php - 处理 Codeigniter 查询中的括号

php - 在 OctoberCMS 的 PHP 数据库中保存模型属性

php - Blueimp Jquery 文件上传 S3 & 调整大小