hql会转换成MapReduce执行,所以应该从MapReduce的运行角度来优化性能,最要解决的问题是数据倾斜的问题。比如:
- 尽量不要使用count(distinct) ,因为此时map端没有去重的操作,可以用嵌套子查询来替代,子表是去重后的表
- 尽量使用MapJoin,在Map阶段把小表读入内存,扫描大表完成Join,就没有MapReduce的shuffle过程,也就不存在数据倾斜的问题
- 聚合函数尽量与groupby一起执行(此时有combiner)
配置上的优化,比如:
- 设置合理的map reduce的task数量
- 合并小文件,减少HDFS的压力
- 改变默认的存储格式:默认是TextFile格式,这种格式不利于查询,可以使用ORCFile,Parquet等存储格式
- 配置Hive的执行引擎ApacheTez(可能会有Bug)
写效率高的hql,比如:
- in/exists用半连接(semi join)替代
- 插入数据时使用多重插入
- 尽量使用子查询不使用关联查询
- 避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描
- 避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
- 字段的前半部分不确定时不要使用模糊查询%、、、
- 不写没有意义的查询
- 可以用表变量代替临时表
- 避免频繁创建和删除临时表
- 尽量避免大事务操作,提高系统并发能力