HiveSQL执行计划
查看SQL的执行计划
Hive提供的执行计划目前可以查看的信息有以下几种:
查看执行计划的基本信息,即explain; 查看执行计划的扩展信息,即explain extended; 查看SQL数据输入依赖的信息,即explain dependency; 查看SQL操作相关权限的信息,即explain authorization; 查看SQL的向量化描述信息,即explain vectorization。
查看执行计划的基本信息
在查询语句的SQL前面加上关键字explain是查看执行计划的基本方法
用explain打开的执行计划包含以下两部分:
- 作业的依赖关系图,即STAGE DEPENDENCIES;
- 每个作业的详细信息,即STAGE PLANS。
执行计划关键词解读如下:
- MapReduce:表示当前任务执行所用的计算引擎是MapReduce
- Map Opertaor Tree:表示当前描述的Map阶段执行的操作信息
- Reduce Opertaor Tree:表示当前秒时的是Reduce阶段的操作信息
Map操作树(Map Operator Tree)信息解读如下:
- TableScan:表示对关键字alias声明的结果集,这里指代student_tb_orc,进行表扫描操作。
- Statistics:表示对当前阶段的统计信息。例如,当前处理的数据行和数据量,这两个都是预估值。
- Filter Operator:表示在之前操作(TableScan)的结果集上进行数据的过滤。
- predicate:表示filter Operator进行过滤时,所用的谓词,即s_age<30 227 and s_name like'%红%'
- Select Operator:表示在之前的结果集上对列进行投影,即筛选列
- expressions:表示需要投影的列,即筛选的列
- outputColNames:表示输出的列名
- Group By Operator:表示在之前的结果集上分组聚合
- aggreations:表示分组聚合使用的算法,这里是count(1)
- keys:表示分组的列,在该例子表示的是s_age
- Reduce output Operator:表示当前描述的是对之前结果聚会后的输出信息,这里表示Map端聚合后的输出信息
- key expressions/value expressions:MapReduce计算引擎,在Map阶段和Reduce阶段输出的都是键-值对的形式,这里key expression和value expressions分别描述的就是Map阶段输出的键(key)和值(value)所用的数据列。这里的例子key expressions指代的就是s_age列,value exporess指代的就是count(1)。
- sort order:表示输出是否进行排序,+表示正序,-表示倒序
- Map-reduce partition columns:表示Map阶段输出到Reduce阶段的分区列,在Hive-SQL中,可以用distribute by指代分区的列。
Reduce中出现但是在Map阶段没有出现的关键词。
(1) compressed:在File Output Operator中这个关键词表示文件输出的结果是否进行压缩,false表示不进行输出压缩。 (2) table:表示当前操作表的信息 (3) input format/out putformat:分别表示文件输入和输出的文件类型 (4) serde:表示读取表数据的序列化和反序列化的方式
查看执行计划的扩展信息
- explain extended,顾名思义就是对explain的扩展,打印的信息会比explain更加丰富,包含以下三部分的内容。
- 抽象语法树(Abstract Syntax Tree,AST)
- 是SQL转换成MapReduce 或其他计算引擎的任务中的一个过程。在Hive 3.0版本中,AST会从explain extended中移除,要查看AST,需要使用explain st命令
- 作业的依赖关系图,即STAGE DEPENDENCIES
- 其内容和explain所展现的一样,不做重复介绍
- 每个作业的详细信息,即STAGE PLANS
- 在打印每个作业的详细信息时,explain xtend会打印出更多的信息,除了explain打印出的内容,还包括每个表的HDFS读取路径,每个Hive表的表配置信息等
查看SQL数据输入依赖的信息
explain dependency用于描述一段SQL需要的数据来源,输出是一个json 格式的数据,里面包含以下两个部分的内容。
- input_partitions:描述一段SQL依赖的数据来源表分区,里面存储的是分区名的列表,格式如下: {"partitionName":"库名@表名 分区列=分区列的值"} 如果整段SQL包含的所有表都是非分区表,则显示为空
- input_tables:描述一段SQL依赖的数据来源表,里面存储的是Hive表名的列表,格式如下: {"tablename":"库名@表名 ","tabletype":表的类型(外部表/部表)"}
explain dependency的使用场景有两个
使用explain dependency识别SQL读取数据范围的差别
-- 代码片段1
explain dependency
select a.s_no
from student_orc_partition a
left outer join student_orc_partition_only b
on a.s_no=b.s_no
and a.part=b.part and b.part>=1
and b.part<=2;
-- 代码片段2
explain dependency
select a.s_no
from student_orc_partition a
left outer 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;
对左外连接在连接条件中加入非等值过滤的条件,如果过滤条件是作用于右表(b表)有起到过滤的效果,则右表只要扫描两个分区即可,但是左表(a表)会进行全表扫描。如果过滤条件是针对左表,则完全没有起到过滤的作用,那么两个表将进行全表扫描。这时的情况就如同全外连接一样都需要对两个数据进行全表扫描。 如果要使用外连接并需要对左、右两个表进行条件过滤,最好的方式就是将过滤条件放到表的就近处,即如果已经知道表数据过滤筛选条件,那么在使用该表前,就用过滤条件进行过滤,一些SQL内置优化器也会做上述的优化,但是还是建议按上面介绍的方式写出来。
查看SQL操作涉及的相关权限信息
- 通过explain authorization可以知道当前SQL访问的数据来源(INPUTS) 和数据输出(OUTPUTS),以及当前Hive的访问用户(CURRENT_USER)和操作(OPERATION)
- Hive在默认不配置权限管理的情况下不进行权限验证,所有的用户在Hive里面都是超级管理员,即使不对特定的用户进行赋权,也能够正常查询。
查看SQL的向量化描述信息
查看SQL的向量化描述信息,我们可以使用explain vectorization命令
什么是向量化模式?
(1)向量化模式是Hive的一个特性,在没有引入向量化的执行模式之前,一般的查询操作一次只处理一行,在向量化查询执行时通过一次处理1024行的块来简化系统底层操作,高了数据的处理性能。 (2)向量化模式的开启方式如下: set hive.vectorized.execution.enabled = true;
向量模式支持的数据类型有:
tinyint; smallint; int; bigint; boolean; float; double; decimal; date; timestamp; string
以下表达式在运行时支持使用向量化模式。
(1) 算数表达式:+、-、*、/、%; (2) 逻辑关系:AND、OR、NOT; (3) 比较关系:<、>、<=、>=、=、!=、BETWEEN、IN(list-ofconstants)as filters (4) 使用AND、OR、NOT、<、>、<=、>=、=、!=等布尔值表达式(非过滤器) (5) IS[NOT]NULL (6) 所有的数学函数,如SIN、LOG和etc (7) 字符串函数:SUBSTR、CONCAT、TRIM、LTRIM、RTRIM、LOWER、UPPER和LENGTH; (8) 类型转换 (9) Hive用户自定义函数,包括标准和通用的用户自定义函数 (10) 日期函数:YEAR、MONTH、DAY、HOUR、MINUTE、SECOND和UNIX_TIMESTAMP (11) IF条件表达式
explain vectorization支持的语法:explain vectorization[only|summary|operator|expression|detail]
- explain vectorization only命令,表示整个执行计划将只显示向量化模式相关的描述信息,其他非向量化模式的描述都将被隐藏。
- 【案例6.9】关闭向量模式的情况下,使用explain vectorization only。
- 关闭向量模式set hive.vectorized.execution.enabled=false; explain vectorization only select count(1) from est;
- 输出结果:
PLAN VECTORIZATION: enabled: false //表示向量模式没有开启 enabledConditionsNotMet: [hive.vectorized.execution.enabled IS false] //开启向量模式的条件不满足,因为hive.vectorized.execution.enabled IS false
- 在上面案例中,如果关闭向量化模式,在输出结果中可以看到PLAN ECTORIZATION一节,描述了该模式没有被开启,原因是由于没有满足enabledConditionsNotMet指代的条件。
- 【案例6.10】开启向量模式的情况下,使用explain vectorization only。
--开启向量模式 set hive.vectorized.execution.enabled=true; explain vectorization only select count(1) from test; -- 输出如下信息: PLAN VECTORIZATION: enabled: true enabledConditionsMet: [hive.vectorized.execution.enabled IS true] STAGE DEPENDENCIES: Stage-1 is a root stage Stage-0 depends on stages: Stage-1 STAGE PLANS: Stage: Stage-1 Map Reduce Execution mode: vectorized Map Vectorization: enabled: true enabledConditionsMet: hive.vectorized.use.vector.serde.deserialize IS true groupByVectorOutput: true inputFileFormats: org.apache.hadoop.mapred.TextInputFormat allNative: false usesVectorUDFAdaptor: false vectorized: true Reduce Vectorization: enabled: false enableConditionsMet: hive.vectorized.execution.reduce.enabled IS true enableConditionsNotMet: ive.execution.engine mr IN [tez, spark] IS false -- 在上面案例中,如果开启了向量化模式,除了有PLAN VECTORIZATION,还包含了STAGE DEPENDENCY和STAGE LANS两部分的信息。
- 【案例6.9】关闭向量模式的情况下,使用explain vectorization only。
将Map和Reduce阶段的向量化模式描述信息简化成如下结构进行解读。
(1) Execution Mode:表示当前的执行模式,vectorized表示当前模式是向量化的模式。 (2) Map Vectorization:表示接下来的缩进信息描述的是关于Map阶段向量化执行模式信息。 (3) enabled:表示该关键词所描述阶段是否已经开启向量化模式,true表示开启,false表示关闭。 (4) enabledConditionsMet:表示该关键词所描述阶段,开启向量化模式已经满足的条件 (5) enableConditionsNotMet:表示该关键词所描述阶段,开启向量化模式未满足的条件。 (6) groupByVectorOutput:表示该关键词所描述的阶段,分组聚合操作是否开启向量化模式,true表示开启。 (7) inputFileFormats:表示该关键词所描述的阶段,输入的文件格式 (8) allNative:是否都是本地操作,false表示不是
案例6.10的输出结果,整个输出结果可以解读为在Map阶段开启了向量化的执行模式,但是在Reduce阶段没有开启(MapReduce计算引擎不支持)
(1) 在Map阶段开启向量化执行模式是因为满足hive.vectorized.use.vector.serde.deserialize IS true这个条件,Reduce阶段没有开启向量化执行模式,是因为除了需要满足hive.vectorized.execution.reduce.enabled IS true,还需要满足hive.execution.engine mr IN[tez,spark这个条件。 (2) 使用explain vectorization summary命令会显示向量化的描述信息和Map/Reduce执行过程的信息,即打印的信息等同于explain vectorization only explain共同输出的结果。 (3) 使用explain vectorization operator命令会显示SQL所有操作的向量化描述信息。 (4) 使用explain vectorization expression命令能够显示SQL表达式的向量化信息,包括explain vectorization ummary和operator的信息 (5) explain vectorization detail命令能够显示更加详细的向量化信息,这些信息包括explain vectorization summary/operator/xpression等上面我们介绍的所有信息。
简单SQL的执行计划解读
简单SQL指不含有列操作、条件过滤、UDF、聚合和连接等操作的SQL,这种类型的SQL在执行时只会用到Map阶段。对应这一类型的SQL被归结为select-from-where型
带普通函数/操作符SQL的执行计划解读
普通函数特指除UDTF(表转换函数)、UDAF(聚合函数)和窗口函数之外的函数,如nvl()、cast()、case when的表达式、concat()和year() 归结为select-function(column)-from–wherefunction(column)或者select-operation-from-where-operation类型
执行计划解读
- select function(column)-from–where-function(column)或者select-expressionfrom-where-expression这种类型的SQL和select-from-where基本型的SQL执行计划可以归为同一种类型。
普通函数和操作符
普通函数可以分为以下几类
(1)数学函数:round()、bround()、bround()、floor()、ceil()、ceiling()、rand()、exp()、ln()、log10()、log2()、log()、pow()、power()、sqrt()、bin()、hex()、unhex()、conv()、abs()、pmod()、sin()、asin()、cos()、acos()、tan()、atan()、degrees()、radians()、positive()、negative()、sign()、e()、pi()、factorial()、cbrt()、shiftleft()、shiftright()、shiftrightunsigned()、greatest()、least()和width_bucket()。 (2)集合函数:size()、size()、map_keys()、map_values()、array_contains()和sort_array()。 (3)类型转换函数:binary()和cast()。 (4)日期函数:from_unixtime()、unix_timestamp()、to_date()、year()、quarter()、month()、day()、dayofmonth()、hour()、minute()、second()、weekofyear()、extract()、datediff()、date_add()、date_sub()、from_utc_timestamp()、to_utc_timestamp()、current_date()、current_timestamp()、add_monhs()、last_day()、next_day()、trunc()、months_between()和date_format()。 (5)条件判断函数:if()、isnull()、isnotnull()、nvl()、colesec()、case when、nullif()和assert_true()。 (6)字符串函数:ascii()、base64()、character_length()、chr()、concat()、context_ngrams()、concat_ws()、decode()、elt()、encode()、field()、find_in_set()、format_number()、get_json_object()、in_file()、instr()、length()、locate()、lower()、lcase()、lpad()、ltrim()、ngrams()、octet_length()、parse_url()、printf()、regexp_extract()、regexp_replace()、repeat()、replace()、reverse()、rpad()、rtrim()、sentences()、space()、split()、str_to_map()、substr()、substring_index()、translate()、trim()、unbase64()、upper()、ucase()、initcap()、levenshtein()和soundex()。 (7)数据脱敏函数:mask()、mask_first_n()、mask_last_n()、mask_show_first_n()、mask_show_last_n()和mask_hash()。 (8)表生成函数(UDTF):explode()、posexplode()、json_tuple()和parse_url_tuple()。 (9)重载是面向对象语言里面的一种概念,和表示函数名一样,但函数的参数类型或者个数不一样。例如,函数substr(string|binary A,int tart),它的重载函数有substr(string|binary A,int start,int len)。
操作运算符可以分为如下几类。
(1)关系操作符:=、>、<、>=、<=、is null、is not null、like、rlike和regexp。 (2)算术运算符:+、-、*、/、div、%、&、|、^和~。 (3)逻辑运算符:and、or、not、!、in、not in和exists。 (4)字符串操作符:||。 (5)复杂类型的构造函数:map(key1,value1,key2,value2,...)、struct(val1,val2,val3,...)、named_struct(name1,val1,name2, val2,...)、array(al1,val2,...)和create_union(tag,val1, val2,...)。 (6)复杂类型的操作运算符:获取数组中的元素,格式为A[下标],获取Map数据中指定key的value格式为M[key],获取Struct类型的特定字段的值, 式为S.x。
带聚合函数的SQL执行计划解读
select-aggr_function-from-where-groupby类型
常见的聚合函数有:avg()、sum()、collect_set()、collect_list()、count()、corr()、covar_pop()、covar_samp()、array()()、histogram_numeric()、max()、min()、percentile()、percentile_approx()、regr_avgx()、regr_avgy()、regr_count()、regr_intercept()、regr_r2()、regr_slope()、regr_sxx()、rer_syy()、stddeve_pop()、stddeve_samp()、variance()、var_pop()和var_samp()。
带聚合函数的SQL执行计划解读,分为如下几类:
- 在Reduce阶段聚合的SQL执行计划;
- 在Map和Reduce都有聚合的SQL执行计划;
- 高级分组聚合的执行计划。
在Reduce阶段聚合的SQL
Map阶段可以分解为以下几步操作:
(1)TableScan。 (2)Filter Operator。 (3)Reduce Output Operator。 在Map 阶段输出数据到Reduce还需要经过一个流程,一般我们统称为Shuffle。Map Operator Tree中的Reduce Output perator中的内容就是描述这些规则和流程的。
- 对Reduce Output Operator关键字的解读
- key expressions:表示Map阶段输出的key,在本例中为s_age。
- sort order:表示Map输出后是否进行排序,+表示正序排序,-表示倒序排序,一个符号代表对一列进行排序,两个符号代表两列,以此类推。
- Map-reduce partition columns:指定一个或者多个列字段,表示在Map 阶段输出数据时,根据这些字段来区分数据。
- value expressions:表示Map阶段输出的Value,在本例中为s_score。如果在MapReduce表达key expressions和value xpressions,则可以用context.write(key expressions,value expressions)来表示。
- 对Reduce Operator Tree中出现的关键字进行解读
- Reduce Operator Tree:表示当前阶段为Reduce阶段的操作。
- Group By Operator:表示分组聚合操作。
- Aggregations:指定分组聚合的算法,这里为avg(value._col0)。其中,VALUE指代的就是Map阶段Reduce Output Operator中所指定的value expressions。Value expressions中的列,在Reduce阶段以_col0,_col1…来表示,因此这里value._col0指代的就是s_score。
- Keys:指定按哪些列进行分组,这里用KEY._col0表示。其中,KEY指代的就是Map阶段Reduce Output Operator中所指定的key expressions。Key xpressions中的列在Reduce阶段以_col0,_col1…表示,因此这里的key._col0其实指代的就是s_age列。
- Mode:表示整个Hive执行过程的模式,complete表示所有的聚合操作都在Reduce中进行
- outputColumnNames:指定输出的列,一般对应keys指定的列数和aggregations声明的算法,每种算法输出的结果占用一列,案例6.17中为_col0,_col1指代的就是s_age,avg(s_score)
在Map和Reduce阶段聚合的SQL
在MapReduce过程中,如果要使用Reduce又没法避免不使用Map,只能使用Combine或者启用数据压缩来减少Map和Reduce之间传输的数据量,以提高这个阶段的效率 在Hive中也提供了相关的配置项目来控制是否启用Map端的聚合,即hive.map.aggr
Group By Operator表示接下来为分组聚合的操作:
(1)aggregations:指定聚合的算法,这里为avg(s_score) (2)keys:指定分组的列,这里为s_age (3)mode:指定聚合的算法,这里采用Hash表形式 (4)outputColumnNames:表示该阶段输出的列 (5)Reduce Output Operator表示接下来描述的是Map输出数据到Reduce阶段这整个过程的操作。 (6)key expressions:表示Map阶段最终输出的key (7)sort order:表示输出是否排序,+表示正序排序,一个+表示对输出的一列进行排序,两个+表示对输出的两列进行排序,以此类推 (8)Map-reduce partition columns:指定一个或者多个列字段,表示在Map 阶段输出数据时,会根据这些字段来区分数据。 (9)value expressions:表示Map阶段最终输出value,案例中的value比较特殊,是一个特殊类型,即struct类型。这是因为在Map阶段并不计算平均值,只是计算总分和对的个数,这两者分别对应struct类型中的sum和count。
高级分组聚合
高级分组聚合指在聚合时使用GROUPING SETS、cube和rollup的分组聚合
(1) GROUPING SETS用法示例:
SELECT a, b, SUM(c) FROM tab1 GROUP BY a, b GROUPING SETS ( a,b )
Grouping sets的子句允许开发者在一个group by语句中,指定多个分组聚合列。所有含有grouping sets的子句都可以用union连接的多个GROUP BY 询逻辑来表示 (2) cube和rollup的用法示例如下:
SELECT a, b, SUM(c)
FROM tab1
GROUP BY a, b with cube;
两者都可以在一个GROUP BY语句中完成多个分组聚合,它们都可以用GROUPING SETS来表达
含grouping sets关键字SQL的执行计划案例
使用高级分组聚合需要确保map聚合是否开启
set hive.map.aggr=true;
explain
select s_age,s_score,count(1)
from student_tb_orc
group by _age,s_score
grouping sets((s_age,s_score));
数据运行结果如下:
STAGE DEPENDENCIES:
Stage-1 is a root stage
Stage-0 depends on stages: Stage-1
STAGE PLANS:
Stage: Stage-1
Map Reduce
Map Operator Tree:
TableScan
alias: student_tb_orc
Filter Operator
predicate: (s_age < 20) (type: boolean) 259
Group By Operator
aggregations: avg(s_score)
keys: s_age (type: bigint), '0' (type: string)
mode: hash
outputColumnNames: _col0, _col1, _col2
Reduce Output Operator
key expressions: _col0 (type: bigint), _col1 (type: string)
sort order: ++
Map-reduce partition columns: _col0 (type: bigint), _col1 (type: string)
value expressions: _col2 (type: struct<count:bigint,sum: double,input:bigint>)
Reduce Operator Tree:
Group By Operator
aggregations: avg(VALUE._col0)
keys: KEY._col0 (type: bigint), KEY._col1 (type: string)
mode: mergepartial
outputColumnNames: _col0, _col2
pruneGroupingSetId: true
Select Operator
expressions: _col0 (type: bigint), _col2 (type: double)
outputColumnNames: _col0, _col1
File Output Operator
compressed: false
table:
input format: org.apache.hadoop.mapred.TextInputFormat
output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKey extOutputFormat
serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
(3) Group By Opertaor中出现的关键字解读。
- aggregations:分组聚合的算法,该案例采用avg算法。
- keys:这是有别于案例6.18,这里多了一列固定列:'0'。
- mode:Hash
- outputColumnNames:最终输出了3列,分别是_col0、_col1和_col2。
- Reduce Output Operator:表示该阶段为Map阶段聚合后的操作
- key expressions:Map阶段最终输出的key,在案例6.19中为s_age和'0'两列。
- sort order:表示是否对Map输出的key expressions列进行排序
- Map-reduce partition columns:表示Map阶段数据输出的分区列,案例6.19中表示用s_age,'0'进行分区。
- value expressions:Map阶段最终输出value,为一个结构体,同案例260 6.18。 (4) Reduce阶段解读如下:
- Group By Operator:表示该阶段为分组聚合的操作
- Aggregations:分组聚合的算法,avg(VALUE._col0)表示对Map阶段输出Value Expressions的_col0取平均值。
- Keys:指定分组聚合的key,有别于案例6.18,有两列,为Map阶段输出的key。
- Mode:mergepartial
- outputColumnNames:表示最终输出的列,案例6.19中用s_age和avg(VALUE._col0)表示。
- pruneGroupingSetId:表示是否对最终输出的grouping id进行修剪,如果为true,则表示在输出列时会将key xpressions或者keys的最后一列进行抛弃,案例6.19中为'0'列。
- Select Operator:表示该阶段处理的投影操作(列筛选)
- Expressions:输出的列表达式为s_age和avg(s_score)列,此为最终输出的列表达式。 (5) SELECT a,b,SUM(c)FROM 261 tab1 GROUP BY a,b GROUPING SETS(a,b),仅用了一个作业就能够实现union写法需要多个作业才能实现的事情,从这点来看能够减少多个作业在磁盘和网络I/时多增加的负担,是一种优化,但是同时也要注意因过度使用高级分组聚合语句而导致的数据极速膨胀的问题。 (6)如果使用该高级分组聚合的语句处理的基表,在数据量很大的情况下容易导致Map或者Reduce任务因硬件资源不足而崩溃。Hive中使用hive.new.job.grouping.set.cardinality配置项来应对上面可能出现的问题,如果SQL语句中处理的分组聚合情况超过该配置项指定的值,默认值(0),则会创建一个新的作业来处理该配置项的情况。
带窗口/分析函数的SQL执行计划解读
Hive提供的窗口和分析函数有如下几种: lead()over(); lag()over(); first_value()over(); count()over(); sum()over(); max()over(); avg()over(); rank()over(); row_number()over(); dense_rank()over(); cume_dist()over(); percent_rank()over(); ntile()over()。
Reduce Output operator阶段出现的关键字解读
- key expressions:表示Map阶段输出key包含两个列s_age和s_score
- sort order:表示在Map阶段对两个列s_age和s_score都进行排序
- Map-reduce partition columns:描述Map的输出结果,分区器采用的分区列,在上面的分区列使用s_age列
- value expressions:Map阶段输出的value值,本例中value表示s_no这一列。 总结一下上面关键字表示的意思。在Map阶段会输出s_no、s_age和s_score这3列。输出数据key为两列,即s_age和s_score,value为s_no列,但是计算引擎不会将key中的两列(s_age和s_score)作为分区列并将s_age和s_score相同的值划分到相同的reduce,而是单独将s_age作为分区列,即SQL over子句里面指定的分区列,并将s_age中相同值的数据传输到相同的Reduce中进行处理。
Reduce一开始就进行列的投影(select Operator),输出了如下3列。
VALUE._col0:对应Map阶段输出的value,即s_no。 KEY.reducesinkkey0:对应Map阶段输出key的第一列,即s_age KEY.reducesinkkey1:对应Map阶段输出key的第二列,即s_score
- 在列投影完成后就是进行窗口/分析函数的操作(PTF Operator)。PTF Operator中个别关键字的解释见案例中的注释。
表连接的SQL执行计划解读
Hive表连接的类型
(1)inner join:返回两个表/数据集连接字段的匹配记录, (2)full outer join:返回左、右两个表/数据集的全部行,不管两边的表/据集中是否存在相互匹配的行。不匹配的行,以空值代替。 (3)left outer join:返回左表/数据集的所有记录,以及右表/数据集中与左表/数据集匹配的记录,如果没有则用空补齐。 (4)right outer join:返回右表/数据集的所有记录,以及左表/数据集中与右表/数据集匹配的记录,如果没有则用空补齐。 (5)left semi join:返回左表/数据集中与右表/数据集匹配的记录,如图6.8所示。 (6)cross join:返回左右两表连接字段的笛卡尔积。
内连接和外连接
- 在HiveSQL的执行计划中,内连接(inner join)与外连接(outer join) 的执行计划基本一致,外连接包含full outer join、right outer join和left outer oin
- 内连接与外连接唯一的区别在于Reduce阶段的Join Operator
- 表连接(Join Operator)。下面我们针对Join出现的关键词,逐一解读。
- Join Operator:表示接下来会处理两表的连接 keys:指定两表连接的条件 0 s_no (type: string),这里0指代Map阶段一个表输出的数据集,该案例指a输出 数据集,s_no表示该数据集和另外一个数据集匹配的条件 1 s_no (type: string),这里1指代Map阶段另外一个表输出的数据集,该案例指b输出 数据集,s_no表示该数据集和另外一个数据集匹配的条件 condition map: Inner Join 0 to 1指定两个数据集进行匹配,并声明了它们之间的连接算法 本例表示0和1数据集进行匹配,连接算法采用inner oin
- 如果使用full、right、left outer join分别替代案例6.21中inner join的写法,它们跟inner join写法所打印的执行计划的区别就只有Condition ap,三者依次对应的执行计划中Condition Map如下: (1) full outer join对应Outer Join 0 to1 (2) left outer join对应Left Outer Join 0 to1 (3) right outer join对应Right Outer Join 0 to1
左半连接
a) 左半连接(left semi join),用于判断一个表的数据在另外一个表中是否有相同的数据。可用于替代Hive中in/exists类型的子查询 b) 左半连接查询的SQL。 select * from tab1 where col1 in (select col1 from tab2) --用left semi join写法如下: select * from tab1 left semi join tab2 on ab1.col=tab2.col c) 在Hive 2.0版本以前不支持in类型的子查询,在hive 2.0及以后可以直接使用in类型的子查询,但是执行计划和基于相同逻辑使用left semi oin打印的执行计划一致,即两个是等价写法,不能存在孰优孰劣。