0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何通过explain来验证sql的执行顺序

Linux爱好者 来源:五分钟学大数据 作者:园陌 2021-09-07 16:24 次阅读

关于 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 语句分析下:

select

sum(b.order_amount) sum_amount,

count(a.userkey) count_user

from user_info a

left join user_order b

on a.idno=b.idno

where a.idno 》 ‘112233’group by a.idno

having count_user》1limit 10;

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

Map 阶段:

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

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

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

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

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

Reduce 阶段:

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

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

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

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

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

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

b87621aa-0fb2-11ec-8fb8-12bb97331649.png

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

首先执行 Stage-5:

b883ad3e-0fb2-11ec-8fb8-12bb97331649.png

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

接下来执行 Stage-2:

首先是 Map 端操作:

b894d690-0fb2-11ec-8fb8-12bb97331649.png

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

然后是 Reduce 端操作:

b8a76c38-0fb2-11ec-8fb8-12bb97331649.png

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

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

最后是 Stage-0 阶段:

b8d9f658-0fb2-11ec-8fb8-12bb97331649.png

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

总结

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

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

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

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

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

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • SQL
    SQL
    +关注

    关注

    1

    文章

    737

    浏览量

    43449
  • 数据库
    +关注

    关注

    7

    文章

    3584

    浏览量

    63344

原文标题:Hive SQL 语句的正确执行顺序

文章出处:【微信号:LinuxHub,微信公众号:Linux爱好者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    plc梯形图顺序执行的原则是什么

    PLC(可编程逻辑控制器)梯形图(或称为梯形逻辑图)是用于描述和编程PLC的一种常用图形化编程语言。它采用了一种顺序执行的原则,即按照图中元素的排列顺序从左到右、从上到下依次执行。 梯
    的头像 发表于 02-05 11:13 633次阅读

    查询SQL在mysql内部是如何执行

    我们知道在mySQL客户端,输入一条查询SQL,然后看到返回查询的结果。这条查询语句在 MySQL 内部到底是如何执行的呢?本文跟大家探讨一下哈,我们先来看下MySQL基本架构~
    的头像 发表于 01-22 14:53 155次阅读
    查询<b class='flag-5'>SQL</b>在mysql内部是如何<b class='flag-5'>执行</b>?

    MySQL的执行过程 SQL语句性能优化常用策略

    回顾 MySQL 的执行过程,帮助介绍如何进行 sql 优化。
    的头像 发表于 12-12 10:26 303次阅读
    MySQL的<b class='flag-5'>执行</b>过程 <b class='flag-5'>SQL</b>语句性能优化常用策略

    MySQL执行过程:如何进行sql 优化

    (1)客户端发送一条查询语句到服务器; (2)服务器先查询缓存,如果命中缓存,则立即返回存储在缓存中的数据; (3)未命中缓存后,MySQL 通过关键字将 SQL 语句进行解析,并生成一颗对应的解析树,MySQL 解析器将使用 MySQL 语法进行
    的头像 发表于 12-12 10:19 187次阅读
    MySQL<b class='flag-5'>执行</b>过程:如何进行<b class='flag-5'>sql</b> 优化

    Oracle如何执行sql脚本文件

    Oracle是一种关系型数据库管理系统,可用于存储、查询和管理大量的数据。在Oracle中,可以通过执行SQL脚本文件来一次性地执行多个SQL
    的头像 发表于 12-06 10:51 2275次阅读

    oracle执行sql查询语句的步骤是什么

    Oracle数据库是一种常用的关系型数据库管理系统,具有强大的SQL查询功能。Oracle执行SQL查询语句的步骤包括编写SQL语句、解析SQL
    的头像 发表于 12-06 10:49 386次阅读

    线程池七大核心参数执行顺序

    线程池是一种用于管理和调度线程执行的技术,通过将任务分配到线程池中的线程进行处理,可以有效地控制并发线程的数量,提高系统的资源利用率和任务处理效率。在使用线程池之前,我们需要了解线程池的七大核心参数
    的头像 发表于 12-04 16:45 358次阅读

    sql的where条件多个and顺序

    SQL中,WHERE子句用于过滤查询结果以提供符合特定条件的记录。当有多个AND操作符时,WHERE子句的顺序并不会影响查询结果,但是正确的AND操作符顺序可以提高查询的可读性和性能。 首先,我们
    的头像 发表于 11-23 11:33 1817次阅读

    sql where条件的执行顺序

    SQL语句中的WHERE条件是用来筛选数据的,它决定了哪些数据会被返回给用户。WHERE条件的执行顺序是影响SQL语句性能的一个重要因素,正确地理解和优化WHERE条件的
    的头像 发表于 11-23 11:31 988次阅读

    数据库SQL的优化

    数据库执行SQL都会先进行语义解析,然后将SQL分成一步一步可执行的计划,然后逐步执行通过分析
    的头像 发表于 10-09 15:43 769次阅读
    数据库<b class='flag-5'>SQL</b>的优化

    静态代码块、构造代码块、构造函数及普通代码块的执行顺序

    在Java中,静态代码块、构造代码块、构造函数、普通代码块的执行顺序是一个笔试的考点,通过这篇文章希望大家能彻底了解它们之间的执行顺序。 1
    的头像 发表于 10-09 15:40 427次阅读
    静态代码块、构造代码块、构造函数及普通代码块的<b class='flag-5'>执行</b><b class='flag-5'>顺序</b>

    什么是索引合优化?探究一下索引合并的几种情况

    在使用 explain 命令分析 SQL 执行情况的时候,type列会描述了表如何被连接,这个列的内容直接反映了SQL执行的效率。
    的头像 发表于 09-26 09:14 376次阅读
    什么是索引合优化?探究一下索引合并的几种情况

    SQL执行顺序图解

    最后我们执行order by 将数据按照一定顺序排序,比如这里按照id排序。如果此时有limit那么查询到相应的我们需要的记录数时,就不继续往下查了。
    的头像 发表于 09-16 12:49 782次阅读
    <b class='flag-5'>SQL</b>的<b class='flag-5'>执行</b><b class='flag-5'>顺序</b>图解

    sql执行顺序优先级是什么

    这是我们实际上SQL执行顺序: 我们先执行from,join来确定表之间的连接关系,得到初步的数据 where对数据进行普通的初步的筛选
    发表于 08-18 12:37 551次阅读
    <b class='flag-5'>sql</b><b class='flag-5'>执行</b><b class='flag-5'>顺序</b>优先级是什么

    系统上线时SQL脚本的9大坑

    即使之前在测试环境,已经执行SQL脚本了。但是有时候,在系统上线时,在生产环境执行相同的SQL脚本,还是有可能出现一些问题。 有些小公司,S
    的头像 发表于 04-24 17:10 379次阅读