[Spark 基础]-- 保持Spark sql join 的字段类型一致

问题

某天,在处理数据时,发现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。

发布了508 篇原创文章 · 获赞 613 · 访问量 201万+

猜你喜欢

转载自blog.csdn.net/high2011/article/details/89892509