【Juicy-Bigdata】Hive SQL执行计划使用

Hive SQL的执行计划能了解SQL程序在转换成相应计算引擎的执行逻辑,从而有针对性的调优。

image-20230225010600367

explain的用法

explain介绍

1
2
3
4
explain query

-- 举例
explain select sum(score) from student_score;

一个HIVE查询会被转换为一个或多个stage组成的序列(有向无环图DAG),可以是MR stage,负责元素存储的stage,负责文件系统的操作的stage

查询结果包含两个大的部分

  1. stage dependencies,各个stage的依赖关系

image-20230224233901090

  1. stage plan:各个stage的执行计划
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
STAGE PLANS:
Stage: Stage-1
Map Reduce
Map Operator Tree:
TableScan
alias: student_score
Statistics: Num rows: 2 Data size: 960 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: score (type: int)
outputColumnNames: score
Statistics: Num rows: 2 Data size: 960 Basic stats: COMPLETE Column stats: NONE
Group By Operator
aggregations: sum(score)
mode: hash
outputColumnNames: _col0
Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE
Reduce Output Operator
sort order:
Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE
value expressions: _col0 (type: bigint)
Execution mode: vectorized
Reduce Operator Tree:
Group By Operator
aggregations: sum(VALUE._col0)
mode: mergepartial
outputColumnNames: _col0
Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE
File Output Operator
compressed: false
Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE
table:
input format: org.apache.hadoop.mapred.SequenceFileInputFormat
output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat
serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
""
Stage: Stage-0
Fetch Operator
limit: -1
Processor Tree:
ListSink

Stage-1 里有Map Reduce,又分为了

  1. Map Operator Tree:Map端的执行计划树
  2. Reduce Operator Tree:Reduce端的执行计划树

包含一些操作

  1. TableScan:表扫描,加载表

    1. alias:表名词
    2. Statistics:表统计信息,数据条数,数据大小等
  2. Select Operator:选取操作

    1. expressions:需要的字段名称和类型
    2. outputColumnNames:输出的列名称
    3. Statistics:表统计信息,包含表中数据条数,数据大小等
  3. Group By Operator:分组聚合操作,常见的属性:

    1. aggregations:显示聚合函数信息

    2. mode:聚合模式,值有 hash:随机聚合,就是 hash partition;partial:局部聚合;final:最终聚合

    3. keys:分组的字段,如果没有分组,则没有此字段

    4. outputColumnNames:聚合之后输出列名

    5. Statistics: 表统计信息,包含分组聚合之后的数据条数,数据大小等

  4. Reduce Output Operator:输出到 reduce 操作,常见属性:

    1. sort order:值为空 不排序;值为 + 正序排序,值为 - 倒序排 序;值为 ± 排序的列为两列,第一列为正序,第二列为倒序
  5. Filter Operator:过滤操作,常见的属性:

    1. predicate:过滤条件,如 sql 语句中的 where id>=1,则此处显示(id >= 1)
  6. Map Join Operator:join 操作,常见的属性:

    1. condition map:join 方式 ,如 Inner Join 0 to 1 Left Outer Join0 to 2

    2. keys: join 的条件字段

    3. outputColumnNames: join 完成之后输出的字段

    4. Statistics: join 完成之后生成的数据条数,大小等

  7. File Output Operator:文件输出操作,常见的属性  compressed:是否压缩

    1. table:表的信息,包含输入输出文件格式化方式,序列化方式等 8. Fetch Operator 客户端获取数据操作,常见的属性:

    2. limit,值为 -1 表示不限制条数,其他值为限制的条数

explain的使用场景

案例一:join会过滤null的值吗

1
select a.id,b.user_name from test1 a join test2 b on a.id=b.id;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
TableScan
alias: a
Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE Filter Operator
predicate: id is not null (type: boolean)
Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE Select Operator
expressions: id (type: int)
outputColumnNames: _col0
Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: N
ONE
...
HashTable Sink Operator
keys:
0 _col0 (type: int)
1 _col0 (type: int)

group by 分组排序会排序吗

1
select id,max(user_name) from test1 group by id;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
TableScan
alias: test1
Statistics: Num rows: 9 Data size: 108 Basic stats: COMPLETE Column stats: NONE Select Operator
expressions: id (type: int), user_name (type: string)
outputColumnNames: id, user_name
Statistics: Num rows: 9 Data size: 108 Basic stats: COMPLETE Column stats:
NONE
Group By Operator
aggregations: max(user_name)
keys: id (type: int)
mode: hash
outputColumnNames: _col0, _col1
Statistics: Num rows: 9 Data size: 108 Basic stats: COMPLETE Column stat
Reduce Output Operator
key expressions: _col0 (type: int)
sort order: +
Map-reduce partition columns: _col0 (type: int)
Statistics: Num rows: 9 Data size: 108 Basic stats: COMPLETE Column st

Group By Operator里有keys:id,sort order:+,说明是按id正序进行排序的

sql执行效率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT
a.id,
b.user_name
FROM
test1 a
JOIN test2 b ON a.id = b.id WHERE
a.id > 2;

---
SELECT
a.id,
b.user_name
FROM
(SELECT * FROM test1 WHERE id > 2) a
JOIN test2 b ON a.id = b.id;

通过执行explain,会发现它们的执行计划一样

explain dependency用法

explain dependency描述SQL需要的数据来源,输出包含:

  1. input_partitions:描述一段 SQL 依赖的数据来源表分区,里面存储的是 分区名的列表,如果整段 SQL 包含的所有表都是非分区表,则显示为空。

  2. input_tables:描述一段 SQL 依赖的数据来源表,里面存储的是 Hive 表 名的列表

使用场景

  1. 快速排除,排除因为读不到相应分区导致的输出异常
  2. 理清表的输入,帮助理解程序的运行

案例一 识别看似等价的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
--代码 1:
select
a.s_no
from student_orc_partition a
inner join
student_orc_partition_only b
on a.s_no=b.s_no and a.part=b.part and a.part>=1 and a.part<=2;
--代码 2:
select
a.s_no
from student_orc_partition a
inner join student_orc_partition_only b
on a.s_no=b.s_no and a.part=b.part where a.part>=1 and a.part<=2;

会发现,代码1仍然用了分区0的数据,代码2则没有

案例二 识别SQL读取数据范围的差别

对左外连接在连接条件中加入非等值过滤的条件,如果过滤条件是作 用于右表(b 表)有起到过滤的效果,则右表只要扫描两个分区即可,但是左表(a 表)会进行全表扫描。如果过滤条件是针对左表,则完全没有起到过滤的作用,那 么两个表将进行全表扫描。这时的情况就如同全外连接一样都需要对两个数据进 行全表扫描。

explain authorization

通过 explain authorization 可以知道当前 SQL 访问的数据来源(INPUTS) 和 数据输出(OUTPUTS),以及当前 Hive 的访问用户 (CURRENT_USER)和操作 (OPERATION)

1
2
3
4
5
6
7
8
9
10
11
INPUTS:
default@student_tb_orc
OUTPUTS:
hdfs://node01:8020/tmp/hive/hdfs/cbf182a5-8258-4157-9194- 90f1475a3ed5/-mr-10000
CURRENT_USER:
hdfs
OPERATION:
QUERY
AUTHORIZATION_FAILURES:
No privilege 'Select' found for inputs { database:default, table:student_ tb_orc,
columnName:s_score}