Dataframe ApacheSpark:计数vs人头(1)。我是空的

Dataframe ApacheSpark:计数vs人头(1)。我是空的,dataframe,apache-spark,Dataframe,Apache Spark,对于给定的spark df,我想知道某个列是否有空值。我的密码是—— if (df.filter(col(colName).isNull).count() > 0) {//throw exception} 这花了很长时间,因为我检查了2列,所以对1个df调用了2次。每次调用它时,我都会看到一个用于计数的作业,因此1个df有2个作业 然后我把代码改成这样- if (!df.filter(col(colName).isNull).head(1).isEmpty) {//throw excep

对于给定的spark df,我想知道某个列是否有空值。我的密码是——

if (df.filter(col(colName).isNull).count() > 0) {//throw exception}
这花了很长时间,因为我检查了2列,所以对1个df调用了2次。每次调用它时,我都会看到一个用于计数的作业,因此1个df有2个作业

然后我把代码改成这样-

if (!df.filter(col(colName).isNull).head(1).isEmpty) {//throw exception}
有了这一变化,我现在看到4个主管职位,而之前只有2个,这增加了总时间

请各位专家帮助我理解为什么工作岗位数量翻了一番?head函数只能调用2次

谢谢你的帮助! N

更新:添加了显示两种情况下的作业的屏幕截图。左边是有计数的,右边是头部。这是两次运行之间唯一不同的线路


很难说只是寻找这行代码,但有一个原因是head可能需要更多的时间<如果在任何部分中有
sort
order\u by
请求洗牌以始终返回第一行,则code>head是一个确定性请求。对于
count
的情况,您不需要对结果进行排序,因此不需要洗牌,这是一个简单的mapreduce步骤。这可能就是为什么你的
头会花更多的时间。

数据帧。头(1)
做两件事- 1.在执行器上的数据帧后面执行操作。 2.将结果的第一行从执行器收集到驱动程序

dataframe.count()-
1.在执行器上的数据帧后面执行操作。如果文件上没有转换并且使用了拼花格式,那么它基本上是扫描文件的统计信息。
2.从执行者向驱动程序收集计数

由于dataframe的源是一个存储统计信息的文件,并且没有任何转换,count()可以比head运行得更快


我不能100%确定为什么有2份工作和4份工作。你能粘贴截图吗

是否为拼花文件创建了数据帧?作业是从稳定源到稳定目标的转换。7个头部作业似乎意味着数据上有7个分区。它正在尝试执行该操作。另一方面,count只是读取文件上的统计信息。数据帧源是一个文件,最终保存到parquet。那么,这是否意味着计数读取源文件的统计数据,就性能而言,这是更好的方法?在数据帧上没有使用任何显式paritionby。如果源文件是拼花地板,则它具有统计信息,并且计数非常快。若源文件不是拼花地板,那个么头部就更好了。依靠大文件将需要更长的时间来感谢您的回复。我已经添加了上面的截图。不是所有的班主任都比班主任慢,但是4个班主任比2个班主任的总时间要长。谢谢你的回复。这里没有进行订购/分拣。我只想检查是否有某些列(本例中为2列)缺少值的行。