示例1:
| visit | --------------------------- | id | add_date | cust_id | --------------------------- | 1 | 2021-09 | 5 | --------------------------- | 2 | 2022-01 | 5 | --------------------------- | 4 | 2022-01 | 5 | --------------------------- | 7 | 2022-01 | 13 | --------------------------- | 9 | 2022-09 | 13 | ---------------------------
计算2022年内总客户访问量:
SELECT
COUNT(*)
FROM
visitWHERE
add_date BETWEEN ‘2022-01’ AND ‘2022-12’;可以看到 cust_id=5 的客户在2022-01访问了2次,期望:同一客户每日只统计一次
优化:
SELECT
COUNT
(DISTINCT CONCAT(customer_id, ‘-‘, DATE_FORMAT(visit_time, ‘%Y-%m-%d’))
) AS total_visitors
FROM
visitWHERE
add_date BETWEEN ‘2022-01’ AND ‘2022-12’;优化过的语句中,我们使用 DISTINCT 关键字来仅计算 customer_id 和 visit_time 的日期部分的每个唯一组合。同时用中间的连字符“-”连接,这两个值以确保唯一性。然后我们使用 COUNT() 函数统计唯一组合的总数,代表访问者的总数,并将其别名为 total_visitors。
示例2:
| visit | --------------------------- | id | add_date | cust_id | --------------------------- | 1 | 2021-09-20 | 5 | --------------------------- | 2 | 2022-01-01 | 5 | --------------------------- | 4 | 2022-01-01 | 5 | --------------------------- | 7 | 2022-01-01 | 13 | --------------------------- | 9 | 2022-09-13 | 13 | ---------------------------
优化:
DATE_FORMAT(visit_time, ‘%Y-%m-%d’)
SELECT
YEAR
(add_date) AS year,MONTH
(add_date) AS month,COUNT(DISTINCT cust_id) AS total_visits
FROM
visitGROUP BY
YEAR(add_date), MONTH(add_date);示例3:
将add_date改为add_time,并将年月日存储为时间戳
优化:
SELECT
COUNT
(DISTINCT cust_id, DAY(FROM_UNIXTIME(add_date))
) as total_visits
FROM
visit;思考:
是使用日期还是时间戳存储?
如果应用程序只需要存储日期而没有任何时间成分,那么使用日期数据类型会更合适,因为它占用的存储空间更小,并且具有更专门的日期计算功能。
另一方面,如果应用程序需要存储访问的日期和时间,那么使用时间戳数据类型会更合适。 如果应用程序需要跟踪插入或更新行的确切时间,时间戳数据类型也很有用。
从 MySQL 优化的角度来看,日期和时间戳数据类型都针对高效查询和索引进行了优化。 但是,使用时间戳数据类型可能会由于其更高的精度而导致索引大小稍大。
总之,选择对 add_date 列使用日期还是时间戳取决于应用程序的具体需要和要求。