Hive知识之优化技巧

文章目录

          • 1、用GROUP BY替换DISTINCT去重
          • 2、使用MAPJOIN
          • 3、使用DISTINCT+ UNION ALL代替UNION
          • 4、聚合分组时视情况使用GROUPING运算符
          • 5、使用 UNION ALL时可以开启并发执行
          • 6、使用函数进行行转列、列转行
          • 7、表连接优化
          • 8、过滤优化
          • 9、解决数据倾斜
            • 9.1 数据倾斜的表现
            • 9.2 数据倾斜的原因及其解决办法

1、用GROUP BY替换DISTINCT去重
  • 在极大的数据量且有很多重复值时,可以先 GROUP BY 去重,再使用 COUNT()计数,效率要高于 COUNT(DISTINCT)
  • 去重字段的重复值时,使用 GROUP BY 效率也会比 DISTINCT 高
SElECT user_name
FROM trade
GROUP BY user_name;
2、使用MAPJOIN
  • HSQL中涉及到多张表的JOIN,当有一张表的大小小于1G时,使用MAPJOIN可以明显的提高SQL的效率。
  • 不过需要注意的是,如果最小的表大于1G,使用MAPJOIN会出现OOM的错误。
SElECT /*+ MAPJOIN(table_a)*/,
		a.*,
		b.* 
FROM table_a a 
JOIN table_b b 
ON a.id = b.id
3、使用DISTINCT+ UNION ALL代替UNION
  • 如果遇到要使用UNION 去重的场景,使用DISTINCT+ UNION ALL比使用UNION 的效果好。
SElECT COUNT(DISTINCT *) 
FROM (
SElECT order_id,user_id,order_type FROM orders WHERE order_type='0'  UNION ALL
SElECT order_id,user_id,order_type FROM orders WHERE order_type='1'  UNION ALL 
SElECT order_id,user_id,order_type FROM orders WHERE order_type='1'
) a;
4、聚合分组时视情况使用GROUPING运算符
  • GROUPING运算符包括GROUPING SETS()、CUBE、ROLLUP

  • GROUPING SETS():在GROUP BY查询中,根据不同的维度组合进行聚合,等价于将不同维度的GROUP BY结果集进行UNION ALL,聚合规则在括号中进行指定。

  • CUBE:根据GROUP BY维度的所有组合进行聚合

  • ROLLUP:以最左侧的维度为主,进行层级聚合,是CUBE的子集

参考链接:
https://blog.csdn.net/weixin_42384784/article/details/105464286

5、使用 UNION ALL时可以开启并发执行
  • 参数设置:set hive.exec.parallel = true
  • 使用 UNION ALL时 开启并发,可以将任务并行执行,提高执行效率。
6、使用函数进行行转列、列转行
  • 使用 lateral view explode进行行转列
  • 使用 concat_ws 进行列转行

参考链接:
https://blog.csdn.net/weixin_42384784/article/details/105465548

7、表连接优化
  • 小表在前,大表在后:Hive假定查询中最后的一个表是大表,它会将其它表缓存起来,然后扫描最后那个表。
  • 使用相同的连接键:当对3个或者更多表进行JOIN连接时,如果每个ON子句都使用相同的连接键的话,那么只会产生一个MapReduce JOB。
8、过滤优化
  • 尽早的过滤数据:减少每个阶段的数据量、对于分区表要加分区,同时只选择需要使用到的字段
  • 逻辑过于复杂时,引入中间表。
9、解决数据倾斜
9.1 数据倾斜的表现
  • 任务进度长时间维持在99%或100%,查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成,因为其处理的数据量和其它的reduce差异过大。
9.2 数据倾斜的原因及其解决办法

(1)空值产生的数据倾斜

  • 如果两个表进行连接时,使用的连接条件有很多空值,建议在连接条件中增加过滤
SELECT ...
FROM ...a
JOIN ...b
ON a.user_id = b.user_id AND a.user_id IS NOT NULL

(2)大小表连接(其中一张表很大,另一张表非常小)

  • 使用 MAPJOIN,将小表放到内存里(参考第2点)
SElECT /*+ MAPJOIN(table_a)*/,
		b.* 
FROM table_a a 
JOIN table_b b 
ON a.id = b.id

(3)两个表连接条件的字段数据类型不一致

  • 将连接条件的字段数据类型转换成一致的
SELECT ...
FROM ...a
JOIN ...b
ON a.user_id = CAST(b.user_id as int)

你可能感兴趣的:(Hive知识)