Hive是通过把HSQL转换成对应MapReduce作业,然后提交到Hadoop上执行。一条HSQL会被转化成多个MapReduce作业,每个作业被称为一个Stage,每个Stage之间有执行顺序和依赖关系,构造成一个DAG图。这些步骤可能包含:元数据的操作,文件系统的操作,MapReduce计算等等。
在HSQL语句之前加一个explain修饰可以看到SQL语句对应的那堆MapReduce作业(执行计划)和其它一些信息。注意这个查询本身是不会执行的,查询计划中的一些信息也可能是Hive帮忙估计的,比如说输入的数据条数、输出的数据条数以及数据的数据大小。这部分内容等到后面讲到Hive元数据的时候再说吧,反正知道下执行计划里面的数据不一定准确就行了。
explain查看执行计划会得到如下两部分内容:
- The dependencies between the different stages of the plan(SQL语句会被划分成多少MapReduce Stage以及Stage之间的依赖关系)
- The description of each of the stages(各个Stage内部的详细内容描述)
例如使用explain查看下面这条SQL的执行计划:
explain select * from
(
select id
from test_table_aaa
where dt='20210202'
and id is not null
group by id
)A
join
(
select id, min(event_time) as min_event_time
from test_table_bbb
where id is not null
group by id
)B
on(A.id = B.id)limit 100
得到如下Stage之间的描述:
STAGE DEPENDENCIES: Stage-1 is a root stage Stage-6 depends on stages: Stage-1, Stage-3 , consists of Stage-7, Stage-8, Stage-2 Stage-7 has a backup stage: Stage-2 Stage-4 depends on stages: Stage-7 Stage-8 has a backup stage: Stage-2 Stage-5 depends on stages: Stage-8 Stage-2 Stage-3 is a root stage Stage-0 depends on stages: Stage-4, Stage-5, Stage-2
这里显示 Stage-1和Stage-3是root stage,root stage是DAG图执行的起点。默认情况下HSQL一次只能执行一个Stage,但是如果enable并行执行的话,多个相互之间没有依赖关系的Stage可以同时执行,这也是提升HSQL性能的一个方法。
Stage-6 depends on stages: Stage-1, Stage-3 表明了Stage之间的执行顺序,consists of 表示Stage6由多个部分组成。
Stage-7 has a backup stage: Stage-2 这个当前暂时还不是很了解...个人理解是如果Stage-7无法执行,那么就会选取备用的Stage-2进行执行。
可以从Yarn上看出当前这整条SQL执行的顺序为:Stage1 -> Stage3 -> Stage2:
Stage中的内容解析:
STAGE PLANS: Stage: Stage-1 Map Reduce // 表示当前的是Map阶段的操作 Map Operator Tree: // 进行Hive表:test_table_aaa的扫描 TableScan alias: test_table_aaa // 当前阶段行数和数据大小的统计信息(rows如果元数据表中不存在的话,那么Hive会帮忙估算,所以说不一定准确) Statistics: Num rows: 1513882 Data size: 3565192110 Basic stats: COMPLETE Column stats: NONE // 对数据集进行过滤,对应where条件 Filter Operator // 过滤时所用的谓词 predicate: uaid is not null (type: boolean) Statistics: Num rows: 756941 Data size: 1782596055 Basic stats: COMPLETE Column stats: NONE // 表示对过滤之后的结果集进行分组聚合操作 Group By Operator // 分组聚合所使用的算法,这里用的是min() aggregations: min(install_time_selected_timezone) // 在uaid这一列上进行分组聚合 keys: uaid (type: string) mode: hash outputColumnNames: _col0, _col1 Statistics: Num rows: 756941 Data size: 1782596055 Basic stats: COMPLETE Column stats: NONE // Map端结果进行输出 Reduce Output Operator key expressions: _col0 (type: string) // 表示输出结果是否排, +表示正序,-表示倒序,一个符号对应一个列 sort order: + // Map阶段输出到Reduce阶段的分区列 Map-reduce partition columns: _col0 (type: string) Statistics: Num rows: 756941 Data size: 1782596055 Basic stats: COMPLETE Column stats: NONE value expressions: _col1 (type: string) // 表示当前的是Reduce阶段的操作(有些SQL语句不一定会有Reduce阶段) Reduce Operator Tree: Group By Operator aggregations: min(VALUE._col0) keys: KEY._col0 (type: string) // 对Map端输出的结果进行最终的合并 mode: mergepartial outputColumnNames: _col0, _col1 Statistics: Num rows: 378470 Data size: 891296850 Basic stats: COMPLETE Column stats: NONE File Output Operator // 文件输出结果进行压缩 compressed: true // 输入输出的文件格式以及读取数据的序列化方式 table: input format: org.apache.hadoop.mapred.SequenceFileInputFormat output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat serde: org.apache.hadoop.hive.serde2.lazybinary.LazyBinarySerDeStage: Stage-2 Map Reduce Map Operator Tree: TableScan // 这里就是是扫描表了,而是上一个MapReduce作业的输出结果 Reduce Output Operator // Map阶段和Reduce阶段输出的都是键-值对的形式,key expression和value expressions分别描述的就是Map阶段输出的键(key)和值(value)所用的数据列 key expressions: _col0 (type: string) sort order: + Map-reduce partition columns: _col0 (type: string) Statistics: Num rows: 378470 Data size: 891296850 Basic stats: COMPLETE Column stats: NONE value expressions: _col1 (type: string) TableScan Reduce Output Operator key expressions: _col0 (type: string) sort order: + Map-reduce partition columns: _col0 (type: string) Statistics: Num rows: 135055067 Data size: 178049618343 Basic stats: COMPLETE Column stats: NONE value expressions: _col1 (type: string) Reduce Operator Tree: // Join操作 Join Operator // 0和1分别代表两个数据集进行join,,并且join的操作为inner join condition map: Inner Join 0 to 1 // 两个数据集进行join的列 keys: 0 _col0 (type: string) 1 _col0 (type: string) outputColumnNames: _col0, _col1, _col2, _col3 Statistics: Num rows: 148560576 Data size: 195854584422 Basic stats: COMPLETE Column stats: NONE // 对应SQL中的limit 100 Limit Number of rows: 100 Statistics: Num rows: 100 Data size: 131800 Basic stats: COMPLETE Column stats: NONE File Output Operator compressed: true Statistics: Num rows: 100 Data size: 131800 Basic stats: COMPLETE Column stats: NONE table: input format: org.apache.hadoop.mapred.TextInputFormat output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
看懂了执行计划能更好理解HSQL的执行流程,哈哈哈,慢慢学习中
参考:
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Explain
https://www.cnblogs.com/wadeyu/p/9809581.html (Hive执行计划分析)
https://blog.csdn.net/jsbylibo/article/details/82465989 (Hive执行计划分析)