最快速验证JOIN键倾斜是运行频次统计SQL,重点看高频key数据量是否远超均值;前3个key频次和>总行数15%即属严重倾斜;需同时检查事实表与维度表,并识别空值、默认值等语义污染型key;小表广播失败或Task级Input Size差异过大(如最大/中位数>5)也是关键判断依据。

查JOIN键的Top N频次分布
直接运行频次统计SQL是最快速的验证方式,重点不是看“有没有高频key”,而是看“高频key的数据量是否远超均值”。比如10亿行事实表中,user_id = 0 占了3亿行,而其他所有user_id加起来才7亿,这就构成严重倾斜。
-
SELECT key, COUNT(*) AS cnt FROM big_table GROUP BY key ORDER BY cnt DESC LIMIT 20—— 必须加LIMIT,避免全表扫描拖垮集群 - 如果结果里前3个key的cnt之和 > 总行数 × 15%,基本可判定为严重倾斜
- 别只查事实表:维度表也要跑一遍,确认它是否也存有同值兜底记录(如
user_id = 0对应一条“未知用户”)
识别语义污染型倾斜key
很多倾斜不是业务自然产生,而是ETL过程埋下的坑:空字符串、'null'、-1、0、999999 这类人工填充的默认值,被大量事实数据引用后就成了“黑洞key”。
- 执行检查语句:
SELECT COUNT(*) FROM table WHERE key IN (-1, 0, 999, 'null', '', 'N/A') - 特别注意:字符串类型的key要同时查
''和' '(带空格),TRIM(key) = ''更稳妥 - 如果该COUNT占表总行数 > 5%,且维度表中恰好存在对应key的一条记录,那就是典型语义污染倾斜
验证小表真实大小是否超标
Spark/Hive常把小表广播,但广播失败会退化为Shuffle JOIN——这时哪怕没热点key,也会因分区不均导致Task负载失衡。根本原因常是小表序列化后体积超标(如含大量长STRING列)。
- 用
DESCRIBE FORMATTED table_name查看TotalSize字段,不是numRows - 若
TotalSize > 2GB,即使只有10万行,也大概率无法广播成功 - 此时看到的“倾斜”现象其实是广播失败后的Shuffle不均,不是key分布问题,加盐无效
观察Task级Input Size差异
这是最硬的证据。现象比SQL统计更真实,因为绕过了采样误差和缓存干扰。
- 在Spark UI的Stage页,点开JOIN对应的Stage → 看每个Task的
Input Size列 - 若最大值 / 中位数 > 5,或单个Task Input Size > 100GB,基本可断定倾斜已发生
- 注意区分:如果所有Task Input Size都很大且接近,那是资源不足或分区数太少;只有1–2个异常高,才是key倾斜
user_id = '0'(字符串)在事实表里占40%,维度表里却存的是user_id = 0(整型),表面看是类型不匹配,实际是两层污染叠加。这种必须先统一类型再统计,否则查不到真凶。

















