如何优化mysql中的巨大左连接?
Posted
技术标签:
【中文标题】如何优化mysql中的巨大左连接?【英文标题】:How to optimize huge left join in mysql? 【发布时间】:2021-03-20 19:45:11 【问题描述】:我的 mysql 数据库中有两个表:
1) 视频
+----+--------+----------+------+----------+
| id | title | category | year | director |
+----+--------+----------+------+----------+
| 1 | Title1 | Cat1 | 2021 | A.K. |
| 2 | Title2 | Cat2 | 2020 | B.C. |
| 3 | Title3 | Cat3 | 2000 | E.A. |
+----+--------+----------+------+----------+
2) Videos_insights
+----------+------------+-------+-------+----------+--------+
| video_id | date | views | likes | dislikes | shares |
+----------+------------+-------+-------+----------+--------+
| 1 | 2021-03-20 | 13 | 2 | 3 | 1 |
| 1 | 2021-03-19 | 35 | 1 | 3 | 3 |
| 1 | 2021-03-18 | 68 | 5 | 6 | 5 |
| 1 | 2021-03-15 | 86 | 3 | 0 | 1 |
| 2 | 2021-02-13 | 234 | 15 | 1 | 34 |
| 2 | 2021-02-12 | 55 | 15 | 2 | 4 |
| 2 | 2021-02-10 | 331 | 255 | 0 | 0 |
+----------+------------+-------+-------+----------+--------+
我想获取在2021-03-01
到2021-03-31
之间观看的视频。所以结果表应该是这样的:
+--------+-------------------------------------------+
| title | date_range |
+--------+-------------------------------------------+
| Title1 | ["2021-03-20 - 2021-03-18", "2021-03-15"] |
+--------+-------------------------------------------+
在我的 MySQL 数据库中,我有大约 100 000 个视频,每个视频有大约 100 个 video_insight。
-
获得结果表的最佳方法是什么?
如何优化?我的意思是我不想让每个 GET 请求都离开加入?这将花费太长时间,我的服务器会烧毁。
【问题讨论】:
。 .如果你想优化某些东西,你应该显示你正在使用的查询。否则,我只是假设问题是如何获得您指定的结果。 【参考方案1】:我会单独表示日期:
select v.id, v.title,
group_concat(date) as dates
from videos v join
video_insights vi
on vi.video_id = v.id
where vi.date >= '2021-03-01' and
vi.date < '2021-04-01'
group by v.id;
请注意,left join
不合适,因为您正在过滤值。
如果您真的想要获取范围,那么您可以使用带有间隙和孤岛方法的窗口函数:
select v.id, v.title, group_concat(date_range)
from videos v join
(select vi.video_id,
concat_ws(' - ', min(vi.date), nullif(max(date), min(date))) as date_range
from (select vi.*,
dense_rank() over (partition by vi.video_id order by vi.date) as seqnum
from video_insights vi
where vi.date >= '2021-03-01' and
vi.date < '2021-04-01'
) vi
group by vi.video_id, date - interval seqnum day
) vi
on vi.video_id = v.id
group by v.id;
【讨论】:
1) 为什么要设置一个不包含在内的日期< '2021-04-01'
?制作<= '2021-03-31
不是更好吗? 2)你知道第二个问题的答案吗?也许做一些快照?
@mickris 。 . .最好使用<
。无论“日期”是否具有时间组件,这都有效。这只是一个预防的好习惯。意外错误。以上是关于如何优化mysql中的巨大左连接?的主要内容,如果未能解决你的问题,请参考以下文章