hive极致优化一,打开解释计划
读懂解释计划
就能够知道,程序运行的前世今生。能够很直观的了解程序运行瓶颈点。 简而言之,优化SQL,先读懂解释计划!
1.1 解释计划的打开方式
hive 如RDBMS一样提供了快捷的打开解释计划的方式,如下,其中EXTENDED|DEPENDENCY|AUTHORIZATION 在实际工作中比较常用,我们着重介绍这个三个
现在我们以一个例子来做个
1.1.1 数据准备
1,创建表
这这里我们创建一个stock_asset_holding位于odata的数据库的表,用格式为"yyyy-MM-dd"形式的busi_date做为分区列,用ORC文件形式存储数据。 字段的含义没必要去理解。至于选用ORC,是在企业实际的生产环境ORC也已经是标准,eg:平安科技大数据平台,百度某项目的数据平台。 ORC对HIVE是一个强有力的补充,后续我们会专门进行剖析。一般建立表后我们会通过describe formmated 命令来查看我们创建运行的结果
上面我们在生产环境中一般关注几个点
Table Type,表的类型,分为外部表和内部表,MANAGED_TABLE就是内部表,EXTENDED_TABLE是外部表
Location,表示表的存储位置
SerDe Library:序列化和反序列化的方式
InputFormat/outputFormat,文件的输入和输出形式,这里是OrcInputFormat/OrcOutputFormat
Compressed表是否进行压缩
Num Buckets/Bucket Columns,分别表示分桶个数,和分桶的列。分桶在HIVE优化中也是一个重要课题,后面也会讲到这里我们先提一下
根据上面的方式我们在创建另外一张表:
2,生成数据 生成的数据,请大家自行生成,我们这边给出我生成的结果
从Partition odata.stock_asset_holding{busi_date=2017-03-17} stats: [numFiles=16, numRows=455199, totalSize=11644188, rawDataSize=0]这样一行 我们看到odata.stock_asset_holding,busi_date=2017-03-17分区,我们生成16个文件,共455199行的数据。 至此我们完成数据的生成。 PS:这里我们使用ANALYZE TABLE命令来快速收集查看分区的统计信息,包括行数。统计信息是一个非常重要的概念在数据库中,大家在这边先有印象,后续有时间在介绍。
1.1.2 explain 格式的解释计划
上面的解释计划一共分为俩个部分:STAGE DEPENDENCIES,STAGE PLANS。 STAGE DEPENDENCIES,用于描述最终生成的作业数,我们看到一个共生成俩个任务,Stage-1,0。stage-0 依赖 stage-1。 STAGE PLANS:用户描述程序的执行逻辑。上面的STAGE PLANS,我们可以看到,每个阶段分为MapReduce俩阶段,为了方便大家理解,我选用一个只有Map,读懂了Map,Reduce阶段也就非常容易了。 所以上面的解释计划读起来就是这样的, stage-1 1. 这个作业执行模式是vectorized,vectorized模式将数据处理从单行处理,转化为批量行进行处理,默认是1024 2. Map Operator Tree,首先进行表扫描(Table scan),预计扫描的行455199,涉及的数据大小 11644188,表别名为dt 3. Filter Operator,行过滤操作,过滤的表达式是trade_id = '66949',预计处理的行是227599,涉及的数据大小 5822081 4. Select Operator,列过滤操作. 这个阶段,我建议采用这样的方式,先读最深的缩进。所以读起来是这样, 4.1 处理的表,输入格式(input format)是org.apache.hadoop.mapred.TextInputFormat,输出格式是org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat 文件的序列化格式org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe 4.2 输出的文件预计是227599行,数据大小是5822081 4.3 输出没有压缩 4.4 一共输出了12列,由于mapreduce中所有的列都是按占位符来表示,所以这里都是用_col[0-11] 4.5 输出每一列表述的数据格式(expressions) stage-0 1. Fetch Operator这表示客户端的取数操作,也就是集群中,这一步是可以略过的
读到这里,我相信大家都有几个疑问,odata.stock_asset_holding,我们创建的是ORC的格式,为什么解释计划给出来的TextInPutFormat, 文件预计事227599行是怎么来的等几个问题。回答这些问题前,大家要先有一个概念,解释计划是Hive根据统计信息所进行的简单描述,不是真正跑的解释计划。 简而言之,这个解释计划是假的,他能帮我们大致理解整个运行过程,却没法帮我们定位问题。
1.1.3 explain extended 格式的解释计划
下面的解释计划很长,但是主要的东西不多,一共分为三个部分
ABSTRACT SYNTAX TREE(AST)抽象语法树,这个在实际工作中,用于快速理清一段代码的逻辑。特别是在给别人的代码做检查的。
STAGE DEPENDENCIES,同1.1.2一样
STAGE PLANS,这个会多一点东西
Path,用于描述输入的分区信息。在想要快速了解程序输入的数据信息,可以用到这个。当然也可以用describe formatted来查看
1.1.4 explain dependency 格式的解释计划
用于描述整个sql需要依赖的输入数据, 分为俩部分input_partitions,input_tables,顾名思义就是输入的表和分区。 实际运用场景:
排错,排查某个程序可能在运行过程略过了某个分区,基本使用方法见例1
理清程序依赖的表的输入,理解程序的运行,特别是理解在俩表join的情况下的依赖输入,见例[2-4]
从例2到例4,我们看到即使限制条件一样,但是full join和outer join都没有按照预先的约束输入对应的分区。所以在hive的使用中,即使是业务上的语意一样(最终的运行结果一样) 也要小心在full/left/right的on子句跟限制条件,因为会造成表的全表扫描,极大降低程序的运行速度。这里有俩条建议:
如果一定要要在A full join B,对A,B表进行查询条件限制,请转换成子查询的形式。
如果一定要要在A left/right outer join B,对A,B表进行查询条件限制,请转换成子查询的形式,也可以在where 子句中进行限制,俩者的explain DEPENDENCY表现形式是一致
1.1.4 explain AUTHORIZATION 格式的解释计划
这个语句用来表达CURRENT_USER的用户对哪些INPUTS有读操作,对哪些OUTPUTS有写操作。 下面的例子是hue的用户,读取odata@stock_asset_holding@busi_date=2017-03-[20-30]的分区,查询出来的结果会暂时存放到hdfs://bigdata-02:8020/tmp/hive/hue/1b128e16-8c27-4a9b-a008-9c2357556ef6/hive_2018-07-31_17-10-04_422_1048252151662607045-1/-mr-10000文件中
原作者:开源中国【osenlin】