问题
某天,在处理数据时,发现Spark sql (版本:Spark-1.6.3 )在进行 join 时,出现了自动截取字符和精度丢失的情况。
已经有人在 Jira 上提出需要WARN或者 Exception ,点击
举例
A 表中的 BigInt 类型和 B表中的 String 类型关联,关联出来的结果重复了,不是我们想要的结果。
表一:t_test_bigint
create table t_test_bigint (
id int comment 'id',
name string comment '名字',
age bigint comment '年龄'
)
ROW FORMAT DELIMITED
NULL DEFINED AS ''
;
插入数据
insert into t_test_bigint values(5,'Tom1',1234567890123456789);
insert into t_test_bigint values(6,'Tom2',12345678901234567892);
insert into t_test_bigint values(7,'Tom3',12345678901234567893);
insert into t_test_bigint values(8,'Tom4',12345678901234567894);
insert into t_test_bigint values(5,'Tom1',12345678901234567);
insert into t_test_bigint values(6,'Tom2',12345678901234568);
insert into t_test_bigint values(7,'Tom3',12345678901234569);
insert into t_test_bigint values(8,'Tom4',12345678901234560);
大于 bigint 的最大限制后,插入的数据中,age 会为 NULL
表二:t_test_string
create table t_test_string (
id int comment 'id',
name string comment '名字',
age string comment '年龄'
)
ROW FORMAT DELIMITED
NULL DEFINED AS ''
;
插入以下数据
insert into t_test_string values(1,'Jam','1234567890123456789');
insert into t_test_string values(2,'Jam2','12345678901234567892');
insert into t_test_string values(3,'Jam3','12345678901234567893');
insert into t_test_string values(4,'Jam4','12345678901234567894');
insert into t_test_string values(1,'Jam','12345678901234567');
insert into t_test_string values(2,'Jam2','12345678901234568');
insert into t_test_string values(3,'Jam3','12345678901234569');
insert into t_test_string values(4,'Jam4','12345678901234560');
注意:age的 数据类型不一样。
分析
1、可能是数据问题:比如数据就是重复
2、可能是join 字段类型不匹配导致:spark sql 执行计划中做了特殊处理
表关联语句:
explain select * from t_test_bigint str left join t_test_string bi on str.age=bi.age;
查看执行计划,发现以下玄机
== Physical Plan ==
Project [id#96,name#97,age#98L,id#99,name#100,age#101]
+- BroadcastHashOuterJoin [cast(age#98L as double)], [cast(age#101 as double)], LeftOuter, None
:- ConvertToUnsafe
: +- HiveTableScan [id#96,name#97,age#98L], MetastoreRelation default, t_test_bigint, Some(str)
+- ConvertToUnsafe
+- HiveTableScan [id#99,name#100,age#101], MetastoreRelation default, t_test_string, Some(bi)
默认自动类型转换为 Double 了,所以关联会出现重复或者关联错误的情况。
解决
为避免出现莫名奇妙的错误,需要将关联字段转化为同一类型(一般会转换为 存储长度较大的 String 类型),然后再 Join。