
# 执行SQL作业时产生数据倾斜怎么办？
#### 什么是数据倾斜？
数据倾斜是在SQL作业执行中常见的问题，当数据分布不均匀的情况下，一部分计算节点处理的数据量远大于其他节点，从而影响整个计算过程的处理效率。
例如观察到SQL执行时间较长，进入SparkUI查看对应SQL的执行状态，如[图1]所示，查看到一个stage运行时间超过20分钟且只剩余一个task在运行，即为数据倾斜的情况。
图1数据倾斜样例   
![](https://support.huaweicloud.com/dli_faq/zh-cn_image_0000001200929158.png "点击放大")
#### 常见数据倾斜场景
- Group By聚合倾斜 在执行Group By聚合操作时，如果某些分组键对应的数据量特别大，而其他分组键对应的数据量很小，在聚合过程中，数据量大的分组会占用更多的计算资源和时间，导致处理速度变慢，出现数据倾斜。
  
- JOIN 操作倾斜 在执行表JOIN操作时，参与JOIN的键在某个表中分布极不均匀，导致大量数据集中在少数几个任务中处理，而其他任务则已完成，造成数据倾斜。
  
 
#### Group By数据倾斜解决方案
取部分数据执行select count(\*) as sum,Key from tbl group by Key order by sum desc查询具体是哪些key引起的数据倾斜。
然后对于倾斜Key单独做处理，加盐让其先将他分为多个task分别统计，最后再对分开统计结果进行结合统计。
例如：如下SQL示例，假设已知倾斜key为'Key01',导致单个task处理大量数据，做如下处理：
```
SELECT
  a.Key,
  SUM(a.sum) AS Cnt
FROM
  (
    SELECT
      Key,
      count(*) AS sum
    FROM
      tbl
    GROUP BY
      Key,
      CASE
        WHEN KEY = 'Key01' THEN floor(random () * 200)
        ELSE 0
      END
  ) a
GROUP BY
  a.Key;
```
#### JOIN数据倾斜解决方案
1. 登录数据湖探索管理控制台，选择"SQL作业"，在要修改的作业所在行的"操作"列，单击"编辑"进入SQL编辑器界面。
2. 在SQL编辑器界面，单击"设置"，在"配置项"尝试添加以下几个Spark参数进行解决。 ![](https://support.huaweicloud.com/dli_faq/zh-cn_image_0000001882995145.png "点击放大")
   参数项如下，冒号前是配置项，冒号后是配置项的值。
   ```
   spark.sql.enableToString:false
   spark.sql.adaptive.join.enabled:true
   spark.sql.adaptive.enabled:true
   spark.sql.adaptive.skewedJoin.enabled:true
   spark.sql.adaptive.enableToString:false
   spark.sql.adaptive.skewedPartitionMaxSplits:10
   ```
   ![](https://support.huaweicloud.com/dli_faq/public_sys-resources/note_3.0-zh-cn.png)
   spark.sql.adaptive.skewedPartitionMaxSplits表示倾斜拆分力度，可不加，默认为5，最大为10。
   
3. 单击"执行"重新运行作业，查看优化效果。
 
