大数据处理之魔幻的NULL

25 篇文章 2 订阅
6 篇文章 1 订阅

前言

null在数据中是一个很特殊的存在,我们实际经历多起生产事故,而且直接就带来直接的经济损失,这个值在实际使用的时候很容易被用错,今天我们来盘点一下null带来的坑吧。

对常见几种空的理解

在这里插入图片描述

比较结果错误

首先还是准备数据


create table tmp_null_test as select id,col from 
values(1,null)
,(2,'v2')
,(3,'v3')
,(null,'v4')
 t(id,col);

select * from tmp_null_test;

id	col
1	\N
2	v2
3	v3
\N	v4

最常见的就是我们期望获取null的值,比如我们很自然的想到列=null的情况

select * from tmp_null_test where col=null;

这个结果很诡异,实际上是查询不到结果的,我们直接看一下如果col=null是怎样的结果:

select id,col,col=null as pk from tmp_null_test;
id	col	pk
1	\N	\N
2	v2	\N
3	v3	\N
\N	v4	\N

特别的神奇,pk结果清一色\N,这样告诉我们获取null这样子是会错误的,null和任何结果比较其实都是无意义的。
怎么办呢?一般有下面些办法:
1、使用 is null

select id,col,col is null as pk from tmp_null_test;
id	col	pk
1	\N	true
2	v2	false
3	v3	false
\N	v4	false

2、使用 COALESCE/nvl函数把null转化掉,再进行过滤

select id,col,COALESCE(col,'')='' from tmp_null_test;
id	col	_c2
1	\N	true
2	v2	false
3	v3	false
\N	v4	false

select id,col,nvl(col,'')='' from tmp_null_test;
id	col	_c2
1	\N	true
2	v2	false
3	v3	false
\N	v4	false

大量null导致倾斜

null带来的倾斜主要有两种,一种是明确告诉你有null,再join我们倒是比较好发现,还一种是在隐式转换的时候带来了null这种很难发现,这个就是null阳谋和阴谋,不管那种情况,在数据体量比较大的时候,其实都会带来极差的性能。

阳谋

一般在数据内部有null的时候,我们直接用来做join,数据量大的时候就是很慢,甚至运行不出来,这种时候也是null的问题,这种情况需要看业务场景是否需要转化掉
在这里插入图片描述

阴谋

有一种情况存在,如下面图中的id,左边是字符串类型,右边其实是double类型,这种时候在做join的时候取值a,b的时候并不能转化成double,这个时候也会产生null
在这里插入图片描述

这种时候产生的null还不是直接产生的,是在做隐式转换的时候发生的,这个时候会导致异常,这种情况很难发现,我记得我们排查了大半年。后面发现问题之后,是需要提前把右边id转换成String类型,再做join。配上sql来说明:
第一次的样子:

select t1.id,t1.name,t2.name from  table1 t1 join table2  t2 on t1.id=t2.id

实际转换路径如下:
在这里插入图片描述
要注意的是这个操作是隐式的,可以在日志上面看到,但是一般人不感知,这种时候会造成null
在这里插入图片描述
解决办法:

select t1.id,t1.name,t2.name from  table1  join 
(selec cast(id as string) as id,name from  table2) t2 on t1.id=t2.id

这种方式是主动把原来是double类型的id主动转换成字符串,带来的是下面的效果:

在这里插入图片描述

null占空间极小,改变了分发策略

在orc格式的存储时代,大量null的数据存在在一个很小的空间中,通过测试发现一个2M的文件,可以存储2亿行的数据,这种时候2m引擎会认为你是小文件,从而直接进行广播,结构就是导致Driver端的OOM,这种时候出现了很多起事故。
怎么解决呢?发现了直接禁止掉了广播了

后记

null需要小心使用,否则~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值