数据冗余 - 加入大型结果集
Posted
技术标签:
【中文标题】数据冗余 - 加入大型结果集【英文标题】:Data redundancy - JOIN with large result set 【发布时间】:2021-05-10 17:30:37 【问题描述】:我遇到了数据冗余问题。我在 mysql 中的 JOIN 查询创建了一个非常大的数据集(~8mb),而很多数据是多余的。经过分析,我可以看到查询速度很快,但数据传输可能需要几秒钟。我有什么选择?
比如说我有两张表
用户:
user_id | user_name |
---|---|
1 | Alex |
2 | Joe |
和购买:
user_id | purchase_id | purchase_amount |
---|---|---|
1 | A | 100 |
2 | B | 200 |
1 | C | 300 |
1 | D | 400 |
如果我只是 LEFT 加入表格
SELECT users.user_id, users.user_name, purchase_id, purchase_amount
FROM Users
LEFT JOIN purchases ON users.id = purchases.user_id
我会得到一个结果:
user_id | user_name | purchase_id | purchase_amount |
---|---|---|---|
1 | Alex | A | 100 |
2 | Joe | B | 200 |
1 | Alex | C | 300 |
1 | Alex | D | 400 |
然而,正如我们所见,user_id 1 和 user_name Alex 存在于三个地方。对于非常大的结果集,这可能会成为一个问题。
我正在考虑使用 GROUP BY 和 GROUP_CONCAT 来减少冗余。这通常是个好主意吗?我的第一个测试似乎有效,但我必须设置 MySQL SET SESSION group_concat_max_len = 1000000;
,这可能不是一件好事,因为我不知道将其设置为什么。
例如,我可以做类似的事情
SELECT user_id, user_name, GROUP_CONCAT(CONCAT(purchase_id, ':', purchase_amount))
FROM Users
LEFT JOIN purchases ON users.id = purchases.user_id
GROUP BY user_id, user_name
最终得到一个结果:
user_id | user_name | GROUP_CONCAT... |
---|---|---|
1 | Alex | A:100,C:300,D:400 |
2 | Joe | B:200 |
我还有其他选择吗?这是要走的路吗?解析连接的列不是问题。我正在尝试解决返回的大型数据集。
【问题讨论】:
您可以选择特定的列而不是users.*
,以减少必须传输的冗余信息量。
我需要所有用户列,就像我在 concat/group 中所做的那样。
另一种选择是在应用程序中进行单独的查询。执行一次查询以获取所有users
信息,循环并执行单独查询以获取他们的购买。这通常被认为是糟糕的设计,但如果您描述的方法效果不佳,它可能是一个可以接受的替代方案。
@Barmar 我已经考虑过了。但这不是一种选择,因为这会导致成千上万的查询。您认为 GROUP_BY 方法有什么问题吗?
那么我认为您被问题中显示的两个选项所困扰。对于GROUP_CONCAT()
,您可以进行第一次查询以获取连接的最大长度,然后将group_concat_max_len
设置为大于该长度。但这可能很昂贵。你可以从COUNT(*) GROUP BY user_id
的最大值估计
【参考方案1】:
-
我们之间可以有临时表吗?
使用 apache spark 的 map reduce 获取所需格式的数据。
【讨论】:
以上是关于数据冗余 - 加入大型结果集的主要内容,如果未能解决你的问题,请参考以下文章