背景
最近我的小伙伴们,在使用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的执行计划,可以从里面获取相关有价值的信息。
博客讲述了在使用SparkSQL进行数据表JOIN操作时,由于字段类型转换导致的数据量异常增长问题。当decimal(20,0)和String类型的字段在转换为double时,因精度丢失产生多对多匹配,从而生成了远超预期的2亿条数据。解决方案是通过cast函数统一转换字段类型为String,避免精度问题。建议在日常分析中使用explain关键字检查SQL执行计划以获取有用信息。
1425

被折叠的 条评论
为什么被折叠?



