有时候一天的充足时间反而不知道该干什么了,之前练车练习变天,回来就只剩学习了,一天空闲时间,却迷失了方向
每日小技巧:
今天不是特别想输出什么东西,其一,被驾校放鸽子了。其二,科目三考试三条道路,太难了。
索性晚上玩着写下了这篇博客。
count(列),count(1),count(*)都是用来计数的,他们之间有什么不同呢?
今天博主带大家探探秘密。
count(列):如果列中有null值,那么这一列不会被记入统计的行数,另外,Hive读取数据的时候,需要将字节流转化为对象的序列化和反序列化的操作。
count(*):如果有Null不会被忽视,count(*)进行统计数据的时候不会读取表中的数据,只会使用HDFS文件中的每一行的偏移量,
count(1)和count(*)相似。
情况分析:
count(列):
通过count函数对ip进行统计,我们可以看到结果,有十万条数据。
我们来看一下这个执行计划,我们会通过执行计划进行分析。
可以看到count(列)只针对相应的字段进行计数,现在map中进行局部的统计,最后在reduce里面进行全局聚合。
count(列)会涉及到字段的筛选,以及数据的序列化和反序列化。
count(*):
同样也是十万条数据,光看上图中的东西没有任何信息量可言。来,看下图
可以看到,我们上图中的执行信息和count(列)的执行信息只有一点不同,就是count()
其实count(*)和count(1)这两个的执行信息是一模一样的,接下来我给大家展示count(1)的执行信息。虽然执行计划一样,但是底层的源码并不一样,后面会通过mr的伪代码来进行解释。
count(1):
虽然三个count最后的结果都是十万条数据,用的时间也不尽相同,可以说几乎差不多,可能因为数据量太小了,无法显示出来到底哪个性能更好。在不同的文件存储下,他们的性能也会有不同的表现。并不是谁一定比谁强,需要看文件存储的格式。
count(列)的伪代码
#count(列)的伪代码
map(inkey,invalue,context)
colsArray= invalue.split("\t")
s_score=colsArray[4] //将数据输出到combine,每一行的记录都会被保存在invalues集合中 context.write(null,s_score)
combine(inkey,invalues,context)
long part_sum=0
part_sum=invalues.size() //行数等于invalues的长度
context.write(null, part_sum)
reduce(inkey,invalues,context)
long all_sum=0
for item in invalues:
all_sum+=item //将在combine中汇总的数据进行加总,得到最终记录数 context.write(null, all_sum)
count(*)的伪代码
map(inkey,invalue,context)
context.write(null,inkey)
combine(inkey,invalues,context)
…//逻辑和count(列)一致
reduce(inkey,invalues,contex
count(1)的伪代码
map(inkey,invalue,context)
context.write(null,invalue) //不对invalue进行操作,直接输出,这边的 invalue就是1 combine(inkey,invalues,context)
… //逻辑和count(列)一致
reduce(inkey,invalues,context)
… //逻辑和count(列)一致
总结:
虽然他们都是计数的,但是他们的底层不同,实现的机制不同,不能说他们是相同的,而且count(列)会对表进行操作,涉及到列的筛选,只对列进行计数,而count(*)和count(1)是对表进行计数