背景
最近我的小伙伴们,在使用spark sql
进行两张数据表关联操作的时候,出现了如下的现象:
表A
含有约89万的数据。
表B
含有约112万的数据。
表A
和表B
之间的关联字段表A
的字段c
,和表B
的字段d
进行inner join
两表进行join
的时候产生了约2亿条数据!!!
但是,其中表A
中的字段c
含有重复值。但是表B
中的字段d
是唯一的。
理论上来说,两个表之间在做inner join
的时候,最大也就只有约200万的数据量。
问题原因
我们使用spark
对数据进行分析。发现表A
的字段c
如上所述是含有重复值的。表B
的字段d
如上所述是唯一的。但是字段c
是decimal(20,0)
字段d
是String
类型的。在两表进行join
的时候,针对decimal(20,0)
的字段c
会转换成double
类型,针对String
的字段d
会转换成double
类型。
好巧不巧的是:两个字段值是形如:1507991832587096065
的19位数字。这19位数字用decimal(20,0)
或者是String
都可以正常表示的。但是使用double
的时候,它会使用科学计数法表示1.50799183258709606E18
这样的话,double
的精度只能到小数点之后的17位。等于就是舍去了最后一位数字。
以上,会导致两个表之间就从多对一的关系,变成了多对多的关系。于是乎,在两表进行join
的时候产生了约2亿条数据
。
处理办法
针对这两个字段在进行join
的时候,使用cast
函数转换数据类型。将decimal(20,0)
数据类型统一转换成String
。问题解决
总结
如果在日常的分析sql的时候,不妨使用一下explain
关键字。利用该关键字,可以分析一下sql
的执行计划,可以从里面获取相关有价值的信息。