前言:hive的执行顺序也是总结mapreduce的执行顺序!!!

关于 sql 语句的执行顺序网上有很多资料,但是大多都没进行验证,并且很多都有点小错误,尤其是对于 select 和 group by 执行的先后顺序,有说 select 先执行,有说 group by 先执行,到底它俩谁先执行呢?

今天我们通过 explain 来验证下 sql 的执行顺序。

在验证之前,先说结论,Hive 中 sql 语句的执行顺序如下:

from .. where .. join .. on .. select .. group by .. select .. having .. distinct .. order by .. limit .. union/union all

可以看到 group by 是在两个 select 之间,我们知道 Hive 是默认开启 map 端的 group by 分组的,所以在 map 端是 select 先执行,在 reduce 端是 group by 先执行

下面我们通过一个 sql 语句分析下:

selectsum(b.order_amount) sum_amount,count(a.userkey) count_user
from user_info a
left join user_order bon a.idno=b.idno
where a.idno > '112233'
group by a.idnohaving count_user>1
limit 10;

上面这条 sql 语句是可以成功执行的,我们看下它在 MR 中的执行顺序:

Map 阶段

  1. 执行 from,进行表的查找与加载;

  2. 执行 where,注意:sql 语句中 left join 写在 where 之前的,但是实际执行先执行 where 操作,因为 Hive 会对语句进行优化,如果符合谓词下推规则,将进行谓词下推;

  3. 执行 left join 操作,按照 key 进行表的关联;

  4. 执行输出列的操作,注意: select 后面只有两个字段(order_amount,userkey),此时 Hive 是否只输出这两个字段呢,当然不是,因为 group by 的是 idno,如果只输出 select 的两个字段,后面 group by 将没有办法对 idno 进行分组,所以此时输出的字段有三个:idno,order_amount,userkey;

  5. 执行 map 端的 group by,此时的分组方式采用的是哈希分组,按照 idno 分组,进行 order_amount 的 sum 操作和 userkey 的 count 操作,最后按照 idno 进行排序(group by 默认会附带排序操作);

Reduce 阶段

6.执行 reduce 端的 group by,此时的分组方式采用的是合并分组,对 map 端发来的数据按照 idno 进行分组合并,同时进行聚合操作 sum(order_amount)和 count(userkey);

7.执行 select,此时输出的就只有 select 的两个字段:sum(order_amount) as sum_amount,count(userkey) as count_user;

8.执行 having,此时才开始执行 group by 后的 having 操作,对 count_user 进行过滤,注意:因为上一步输出的只有 select 的两个字段了,所以 having 的过滤字段只能是这两个字段;

9.执行 limit,限制输出的行数为 10。


上面这个执行顺序到底对不对呢,我们可以通过 explain 执行计划来看下,内容过多,我们分阶段来看。

1.首先看下 sql 语句的执行依赖:

我们看到 Stage-5 是根,也就是最先执行 Stage-5,Stage-2 依赖 Stage-5,Stage-0 依赖 Stage-2。

2.首先执行 Stage-5:

图中标 ① 处是表扫描操作,注意先扫描的 b 表,也就是 left join 后面的表,然后进行过滤操作(图中标 ② 处),我们 sql 语句中是对 a 表进行的过滤,但是 Hive 也会自动对 b 表进行相同的过滤操作,这样可以减少关联的数据量。

3.接下来执行 Stage-2:

  • 首先是 Map 端操作:

先扫描 a 表(图中标 ① 处);接下来进行过滤操作 idno > '112233'(图中标 ② 处);然后进行 left join,关联的 key 是 idno(图中标 ③ 处);执行完关联操作之后会进行输出操作,输出的是三个字段,包括 select 的两个字段加 group by 的一个字段(图中标 ④ 处);然后进行 group by 操作,分组方式是 hash(图中标 ⑤ 处);然后进行排序操作,按照 idno 进行正向排序(图中标 ⑥ 处)。

  • 然后是 Reduce 端操作:

首先进行 group by 操作,注意此时的分组方式是 mergepartial 合并分组(图中标 ① 处);然后进行 select 操作,此时输出的字段只有两个了,输出的行数是 30304 行(图中标 ② 处);接下来执行 having 的过滤操作,过滤出 count_user>1 的字段,输出的行数是 10101 行(图中标 ③ 处);然后进行 limit 限制输出的行数(图中标 ④ 处);图中标 ⑤ 处表示是否对文件压缩,false 不压缩。

执行计划中的数据量只是预测的数据量,不是真实运行的,所以数据可能不准!

4.最后是 Stage-0 阶段:

限制最终输出的行数为 10 行。

总结

通过上面对 SQL 执行计划的分析,总结以下几点:

  1. 每个 stage 都是一个独立的 MR,复杂的 hive sql 语句可以产生多个 stage,可以通过执行计划的描述,看看具体步骤是什么。

  2. 对于 group by 的 key,必须是表中的字段,对于 having 的 key,必须是 select 的字段。

  3. order by 是在 select 后执行的,所以 order by 的 key 必须是 select 的字段。

  4. select 最好指明字段,select * 会增加很多不必要的消耗(CPU、IO、内存、网络带宽)。

Hive SQL语句的正确执行顺序相关推荐

  1. SqlServer中Sql语句的逻辑执行顺序

    准备数据 Sql脚本如下,两张表,一张客户表Customers只包含customerid和city字段,一张订单表Orders包含orderid和customerid(关联Customers的cust ...

  2. SQL语句中的执行顺序

    这也是一篇不完全的翻译,有兴趣的读者可以查看原文. 下面的SQL语句的执行顺序只是逻辑上的顺序,在实际中优化器会选择最省时省力的顺序: FROM:这个只需要说一点的是JOIN这一步包含在FROM里面, ...

  3. mysql语句的执行顺序_SQL语句完整的执行顺序(02)

    这是对SQL语句完整的执行顺序(01)的补充: 数据库是mysql,使用的数据库表名称是my_student. 表的完整数据信息是: 完整语法是: Select [select选项] 字段列表[字段别 ...

  4. beeline执行sql语句_由“Beeline连接HiveServer2后如何使用指定的队列(Yarn)运行Hive SQL语句”引发的一系列思考...

    背景 我们使用的HiveServer2的版本为0.13.1-cdh5.3.2,目前的任务使用Hive SQL构建,分为两种类型:手动任务(临时分析需求).调度任务(常规分析需求),两者均通过我们的We ...

  5. SQL Select语句完整的执行顺序:

    SQL Select语句完整的执行顺序: 1.from子句组装来自不同数据源的数据: 2.where子句基于指定的条件对记录行进行筛选: 3.group by子句将数据划分为多个分组: 4.使用聚集函 ...

  6. select语句的逻辑执行顺序,你知道吗?

    回顾一下上一篇博客说到的问题: mysql -uroot -ptest 我们不能赤裸裸的将账户和密码就这样写在你的脚本里,这并不是一个好做法.所有能够访问你脚本的人都会知道数据库的用户账户和密码.要解 ...

  7. 基础架构:一条sql语句是如何执行的?

    一条sql语句是如何执行的? 一条sql语句是如何执行的? 接下来我打算更新一本mysql基础架构专栏,此文章来自与林晓斌老师的极客时间收费栏目,现免费分享给大家 这是专栏的第一篇文章,我想来跟你聊聊 ...

  8. SELECT语句定义和Select语句完整的执行顺序

    SELECT语句定义: 一个完成的SELECT语句包含可选的几个子句.SELECT语句的定义如下:<SELECT clause> [<FROM clause>] [<WH ...

  9. 一条更新SQL语句是如何执行的?

    前言 在上篇文章<一条查询SQL语句是如何执行的?> 介绍了一些常用组件,一般是经过连接器.分析器.优化器.执行器等功能模块,最后到达存储引擎.本文是介绍一条更新语句如何执行,还会介绍一写 ...

最新文章

  1. 【WEB API项目实战干货系列】- API登录与身份验证(三)
  2. pytorch加载预训练 加载部分参数
  3. java joda 获取utc时间_java – 使用JodaTime以毫秒为单位的UTC到本地时间
  4. 一篇文章让你了解灾备指标:RPO与RTO
  5. 将bgr彩色矩阵归一化到0-255之间 【RGB image normalization】
  6. 串口数据字节位的理解
  7. 如何删除Win All的流氓程序文件
  8. 关于解决“用系统U盘安装win7却提示‘缺少所需的CD/DVD驱动器设备驱动程序’”的问题
  9. 同步调用、异步调用和回调函数
  10. 【元胞自动机】基于matlab六边形网格六方元胞自动机【含Matlab源码 1362期】
  11. group policy client服务未能登录,拒绝访问
  12. 新下载的工程,启动tomcat出现识别文件失败的现象。No qualifying bean of type 'com.kanq.platform.cert.mapper.CertificateSjdr
  13. cppcheck的安装与使用
  14. 计算机语言底层用汉语拼音设计,对汉语拼音设计方案认识(10页)-原创力文档...
  15. python 随机森林分类 代码
  16. Discuz x2 数据字典
  17. 计算机英语名词简释(转)
  18. 编程猫python讲师面试_【编程猫工资|编程猫待遇怎么样】-看准网
  19. MT2503D完整规格书,MT2503D daatsheet资料下载
  20. 汤晓丹的第四版计算机操作系统--第六章总结概述

热门文章

  1. java计算机毕业设计仟侬堂茶具网站源码+数据库+系统+lw文档+mybatis+运行部署
  2. linux命令解释pwd,Linux中pwd命令有什么用
  3. Graphviz的使用指南
  4. android touch事件无反应,移动端touch事件
  5. 年轻人不讲武德,一起聊聊List集合(五)
  6. AppleWatch出货量下降,三星智能手表创下历史新高
  7. 让手机支持OTG,不看绝对后悔! - 我也做一回搬运工,解决RFID读卡器OTG支持问题...
  8. 美股创历史新高,巴菲特却继续减持,他葫芦里卖的是什么药?
  9. Armadillo矩阵库的使用(一)之Armadillo的安装
  10. hackme.inndy rsbo2 经验总结