Hive-SQL优化与细节
持续记录,主要涉及设置相关。
常规
- in/exist 使用 left semi join 替代
- 设计合理分层数仓,减少复杂SQL与job数量
- join 小表 放左侧
- 合理使用map join
- 避免join两表键值是多对多
- 使用group by处理count(distinct )
- 谓词下推
实战优化+与bug战斗
实例1
在某些特殊的带join的SQL会异常缓慢,甚至卡在map阶段,需要将默认为true的配置取消
set hive.auto.convert.join = false;
原因是默认配置优化了map join的顺序,并触发了bug,这个在hive1.1版本依然存在。
https://issues.apache.org/jira/browse/HIVE-4502
实例2
遇到类似问题:
https://stackoverflow.com/questions/28674753/hive-runtime-error-while-processing-row-in-hive
ORC格式的hive表在MR时会报未知原因的错,比如说error evaluating 某个字段值。
原因是CDH5中的bug
答应我,别在CDH5中使用ORC好吗
主要是因为使用ORC格式的文件与Hive的矢量化特性不兼容导致
方法1:
set hive.vectorized.execution.enabled=false;
set hive.vectorized.execution.reduce.enabled=false;
方法2:
使用parquet格式存储
实例3
遇到一个很奇怪的Join现象,左右表包含连接值('2019010325112242312')的数据都只有一条,但是左连接或内连接出来竟然有两条数据
select
orders.`order_sn`,
details.`order_sn` from
( select order_sn from A
where dt='20190504' and order_sn='2019010325112242312'
) as orders
left join --订单详情表
( select order_sn from B
where dt='20190504'
) as details on orders.order_sn=details.order_sn;
对比左右表的建表语句发现,左表字段order_sn数据类型是String而右表的是bigint
SELECT '2019010325112242423'=cast('2019010325112242312' as BIGINT);
//最后3位不同时为true,4位不同则为false,而长度再多一位对比则为NULL
通过实验测试语句发现,不同的string值在转换成bigInt类型后对比会因为精度问题而产生相等判断的bug。
http://support.sas.com/documentation/cdl/en/fedsqlref/67364/HTML/default/viewer.htm#p1k4nui8i2daihn1n5ll3nzsx0ww.htm