SQL性能优化

SQL性能优化

前言

SQL优化是一个长期的过程。很多优化原则并不是固定不变的,应根据实际业务要求进行。管理员应经常检查TOP SQL,及时与开发人员进行沟通,根据实际情况制定优化策略。原则上讲,SQL优化是应用开发人员的事。

第1条

SQL语句多表关联时,应使用别名。相关字段通过别名进行应用。使用别名可以减少优化器查找对象关联的复杂度,降低解析代价。

第2条

对于关键SQL语句,尽量简化,不要包含太多的层次,避免执行计划错误的可能,原则上不能超过5层;

第3条

应尽可能避免order by,group by,distinct等引起不必要排序的操作。

第4条

应尽量使检索条件的两侧类型一致,避免where查询条件做隐型转换时后出现混乱,导致产生错误的执行计划。

第5条

注意like的使用方法,变量%要注意查询范围, %在开头或者末尾,选择性最好。

第6条

防止group by的key分布不均匀,在SQL执行前设置防倾斜的参数:

set hive.groupby.skewindata=true。

有数据倾斜的时候进行负载均衡,当选项设定为true,生成的查询计划会有两个MR Job。第一个MR Job中,Map 的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MR Job再根据预处理的数据结果按照Key分布到Reduce中(这个过程可以保证相同的Key被分布到同一个Reduce中),最后完成最终的聚合操作。
当group by‘常量’时,该设置无效。

第7条

join时key分布不均匀会导致数据倾斜,可以有两种解决方案:

1.如果join的两边有一个是小表,可以把join改成map join来处理。

2.倾斜的key用单独的逻辑来处理,例如经常发生两边的key里有大量null数据导致了倾斜。则需要在join前先过滤掉null的数据或者补上随机数,然后再进行join。

如:

select * from log a 
  left outer join users b
  on case when a.user_id is null then concat('hive',rand()) else a.user_id end = b.user_id;

如果key为null的数据不需要使用建议先过滤掉key值为null的数据,当然大部分情况下,可能倾斜的值不是null,而是有意义的数据,那么这时候就需要把这类数据单独拎出来单独处理,分而治之。

第8条

count distinct时也容易发生数据倾斜,常见于固定的特殊值较多的场景。count distinct时,将值为空的情况单独处理,如果只是计算count distinct,可以不用处理,直接过滤,在最后结果中加1。如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union。

第9条

当一个大表和一个或多个小表做JOIN时,要求使用MAPJOIN,性能比普通的JOIN要快很多。 另外,MAPJOIN 还能解决数据倾斜的问题。

  1. LEFT OUTER JOIN的左表必须是大表

  2. RIGHT OUTER JOIN的右表必须是大表

  3. FULL OUTER JOIN不能使用MAPJOIN

  4. MAPJOIN支持小表为子查询

  5. 使用MAPJOIN时需要引用小表或是子查询时,需要引用别名

数据倾斜

数据倾斜原因:

1.key分布不均匀

2.业务数据本身的特性

3.建表时考虑不周

4.某些Sql语句本身就有数据倾斜

(目的是如何将数据均匀的分配到各个reduce中)

处理数据倾斜主要的方法:

1.map join

2.map端combine

3.给key赋前缀进行扩容

4.避免使用造成单reduce的函数

原文地址:https://www.cnblogs.com/SAN-W/p/14277054.html