20多个表,每个都有userId 和其他几个属性,要根据userId把他们全部汇总,如何处理?

20多个表,每个表都有userId 和几个属性,要把他们全部都拼到一张表,怎么处理?

按 userId 汇总关联 20 张表。

面对 20多张表 的全量字段合并(宽表化),这是一个 ETL(抽取、转换、加载) 过程。

如果直接用 JOIN 拼 20 张表,上百万行数据在执行时会产生巨大的笛卡尔积风险,且极易触发 MySQL 的溢出或者超时。

方案一:SQL 离线宽表化(推荐)

采用 "主表 + 逐步左连接" 的方式,分步写入一张中间宽表。

1. 创建目标宽表(大宽表)

先创建一个包含所有字段的宽表。

注意:关联字段必须全部建有索引。

这 20 张表参与关联的 user_id 必须全部建有索引。

sql 复制代码
CREATE TABLE tmp_user_profile_20260414 AS 
SELECT user_id FROM tmp_data_20260414;

ALTER TABLE tmp_user_profile_20260414 ADD PRIMARY KEY (user_id);
2. 分步更新(分而治之)

每张表单独更新到宽表中,这样即使某张表数据有问题,也不会影响整体流程。

使用 sql 的 Update Join 处理。

sql 复制代码
-- 拼入数据
UPDATE tmp_user_profile_20260414 w
JOIN (SELECT user_id, AVG(diff) as avg_sleep FROM t_sleep GROUP BY user_id) s 
  ON w.user_id = s.user_id
SET w.avg_sleep_seconds = s.avg_sleep;

-- 重复上述步骤,直到 20 张表全部拼完

方案二:Java 内存并行映射(高性能,适合逻辑复杂)

如果某些表的属性需要复杂的 Java 逻辑计算,建议在后端处理:

  1. 定义 Map 容器:Map<Long, UserProfileDTO> profileMap
  2. 并行查询:使用 CompletableFuture 并行开启 20 个任务,每个任务查一张表并按 user_id 塞入 Map。
  3. 批量写入:拼装完成后,利用 MyBatis 的 batchInsert 一次性落库。
相关推荐
chuan.bai1 小时前
Java RAG 实战(第 11 篇):RAG 知识工作台网页
java·开发语言·人工智能
0x534 小时前
网站通信(一)
java
Terra.K4 小时前
Java异常学习[特殊字符]
java·开发语言·学习
葡萄城技术团队5 小时前
InfluxDB 2\.x 深度解析:核心架构、Flux 函数与制造业落地指南(三)
java·开发语言·架构
Super 含6 小时前
Android 启动优化(五):线程、GC 与 IO 为什么会拖慢启动?
java·服务器·数据库
counting money6 小时前
Java IO流详解:从InputStream到文件操作实战
java·开发语言·python
灯澜忆梦6 小时前
【MySQL17】进阶篇 | InnoDB引擎
数据库·mysql
程序员小八7776 小时前
上海百度B端java后端日常实习一面
java·开发语言
mldong7 小时前
零依赖的秘密:8 大 SPI 设计
java·架构
布莱克6058 小时前
理解数据库聚簇索引:原理、优势与适用场景
数据库·mysql