我有一个有几百万行数据的表。我在 id 上有一个主键,在 col2、col3、col4 和 my_date 上有一个复合唯一键。 示例数据显示在这里...
id col2 col3 col4 my_date
1 1 1 1 2020-01-03 02:00:00
2 1 2 1 2020-01-03 01:00:00
3 1 3 1 2020-01-03 03:00:00
4 2 1 1 2020-02-03 01:00:00
5 2 2 1 2020-02-03 02:00:00
6 2 3 1 2020-02-03 03:00:00
7 3 1 1 2020-03-03 03:00:00
8 3 2 1 2020-03-03 02:00:00
9 3 3 1 2020-03-03 01:00:00
我想获取最小和最大日期,按 col2 分组。
规则是...
我的想法是从第一个 id 中获取最小日期并添加 1 周。然后使用此数据作为范围限制器来获取每个 col2 组的最小日期,以及相反的最大日期。
我创建了以下查询...
SELECT t1.col2, t1.min_date, t2.max_date
FROM (
SELECT min(table.my_date) AS min_date, table.col2 AS col2
FROM table
JOIN (
SELECT table.id AS id, date_add(table.my_date, interval 7 day) AS min_date
FROM table
JOIN (
SELECT min(table.id) AS min_id
FROM table
WHERE table.col4 = 1
) AS t3
ON table.id = t3.min_id
) AS t3
ON table.my_date < t3.min_date
GROUP BY table.col2
) AS t1
JOIN (
SELECT max(table.my_date) AS max_date, table.col2 AS col2
FROM table
JOIN (
SELECT table.id AS id, date_sub(table.my_date, interval 7 day) AS max_date
FROM table
JOIN (
SELECT max(table.id) AS max_id
FROM table
WHERE table.col4 = 1
) AS t5
ON table.id = t5.max_id
) AS t4
ON table.my_date > t4.max_date
GROUP BY table.col2
) AS t2
ON t1.col2 = t2.col2
查询运行正常并返回正确的结果。目前运行大约需要 12 秒。
是否有更好的方法来编写此查询以提高性能/可读性?
“我想获取最小和最大日期,按 col2 分组。” -- 然后简单地有
INDEX(col2, my_date)
你现在有
UNIQUE(col2, col3, col4, my_date)
,对吗?如果你愿意洗牌,你就不需要我的额外索引:UNIQUE(col2, my_date, col3, col4)
.
那么,这是相当高效的:
SELECT col2, MIN(my_date), MAX(my_date)
FROM table
GROUP BY col2;
EXPLAIN SELECT ...
将通过说“使用索引”来显示索引正在“覆盖”。