問題
某天,在處理數據時,發現Spark sql 在進行 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 了,所以關聯會出現重複或者關聯錯誤的情況。
解決
爲避免出現莫名奇妙的錯誤,需要將關聯字段轉化爲同一類型,然後再 Join。