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 一次性落库。
相关推荐
Cc.Y1 小时前
Java零基础入门:字符串深度掌握——从基础API到StringBuilder性能优化
java·开发语言·性能优化
nhdh6 小时前
B+树揭秘:MySQL索引核心原理全解析
数据结构·b树·mysql
shuoshuohaohao6 小时前
MyBatis 小知识点
java·spring·mybatis
海上小飞龙6 小时前
【KMP算法-下篇】同一道题:Java 库函数 2600 微秒,手写 KMP 16 微秒
java·开发语言·算法
谢亮_vipxieliang7 小时前
泛型擦除、通配符与 PECS 一次讲透
java·面试
八解毒剂7 小时前
【计组】中央处理器CPU
java·开发语言·计算机组成原理
打工仔折腾 AI8 小时前
工业场景下时序库与实时计算一体化架构选型实践对比
java·开发语言·后端·python·性能优化·架构·ai agent 实战
余槐i8 小时前
MySQL 深分页从 4 秒到 60 毫秒:延迟关联减少回表的实测与代价
mysql·性能优化·sql优化·执行计划·慢查询优化
ZealSinger8 小时前
Java虚拟线程上线后瓶颈转移到哪看三层
java·开发语言·firefox
2601_961133288 小时前
盘立方软件指标文华期货公式下载
java