select 语句执行
分析购买苹果手机iphone7的情况
select order_id,buyer_id,cate_name from order_table where day='20170101' and cate_name='iphone7';
1
输入分片:在实际项目中,订单表通常会进行分区,一般按照自然天进行分区,SQL限制day=20170101实际上就限制了day=20170101的分区文件(如果不限制分区条件的话,hadoop会读取订单的所有文件,假如有两年730天的订单,那么就会读取这两年的所有订单文件,这就是上面所说的不恰当的Hive SQL,这就会给Hadoop集群带来很多不必要的成本和开销)
Map阶段:Map任务的个数由分片的个数决定,每个Map任务接收自己的分区文件,并在map函数中进行检查:商品类是否为iphone7?不是的话,将其过滤;是的话,获取select语句指定的列值,并保存在本地文件中
Shuffle和Reduce:此SQL任务不涉及数据的重新分发与分布,不需要启动任何的Reduce任务
输出文件:直接合并Map任务的输出文件到输出目录
group by语句执行
分析购买iphone7客户在1各城市中的分布情况
select city,count(order_id) as iphone7_count from orders_table where day='20170101' and cate_name='iphone7' group by city;
1
Hive SQL的group by 语句涉及数据的重新分发与分布,因此其执行过程完整的包含了MapReduce任务的执行过程
输入分片:文件依然是day=20170101的分区文件,其输入分片和个数同select语句
Map阶段:Hadoop集群同样启动三个Map任务,处理对应的三个分区文件,每个map任务处理其对应分片文件中的每行,检查其商品类目是否是iphone7,如果是,则输出<city,1>的键值对,如果不是则不write
Combiner:如果指定了Combiner操作,其好处是可以去除冗余输出,避免不必要的的后续处理的网络传输开销等。但是Combiner操作时有风险的,使用它的原则是Combiner的输出不会影响到Reduce计算的最终输出。例如:如果是求总数、最大值、最小值、可以使用它,但是如果在求平均值的时候用它,那么最终的结果可以会出错。
Shuffle与Reduce 阶段:将每个Map Task将相同城市的数据进行聚合
输出文件:合并Reduce Task任务的输出文件合并到输出目录
join语句执行
分析购买iphone7的客户的年龄分布情况,订单表只包含了客户的ID,客户的年龄保存在另一个买家表中,使用join
select t1.order_id,t1.buyer_id,t2.age
from
(select order_id,buyer_id from orders_table where day='20170101' and cate_name='iphone7' ) t1
join
(select buyer_id,age from buyer_table where buyer_status='有效') t2
on t1.buyer_id=t2.buyer_id
输入分片:输入文件为第一个MapReduce和第二个MapReduce任务的输出文件
Map阶段:集群会对两个输出文件启动相应数量的MapTask,比如第一个输出文件包含了两个split,那么第一个输出文件就会启动两个map task
shuffle阶段:shuffle过程主要是partition,即根据其join的列进行数据的重新分布分发的过程。join语句partition列即为join的列,在此为buyer_id,因此对于输出文件1和输出文件2对应的所有Map任务,其输出会根据buyer_id的值进行数据的重新分发与发布
reduce阶段:是根据join键值将其他列关联进来的过程,MapTask1-1的order_id=1003 buyer_id=222的行会被分发到ReduceTask1上,而MapTask2-1的buyer_id=222 age=25的列也会被分发到Reduce Task1上,此时Reduce Task1就根据buyer_id将它们的值关联合并为一行,并写入本地的结果文件中