HiveSql的原理解析,与mysql差异

HiveSql的原理解析

HiveSQL底层默认是基于MR程序运行的,我们分析HiveSQL的运行原理之前,首先看一下MR程序实现一些SQL操作的基本原理。

MapReduce实现基本SQL操作的原理

MR中join的实现原理

select u.name, o.orderid from order o join user u on o.uid = u.uid;
在map的输出value中为不同表的数据打上tag标记,在reduce阶段根据tag判断数据来源。MapReduce的过程如下:
在这里插入图片描述

MR中group by的实现原理

select rank, isonline, count(*) from city group by rank, isonline;
将GroupBy的字段组合为map的输出key值,利用MapReduce的排序,在reduce阶段保存LastKey区分不同的key。MapReduce的过程如下(当然这里只是说明Reduce端的非Hash聚合过程):
在这里插入图片描述

MR中distinct的实现原理

select dealid, count(distinct uid) num from order group by dealid;
当只有一个distinct字段时,如果不考虑Map阶段的Hash GroupBy,只需要将GroupBy字段和Distinct字段组合为map输出key,利用mapreduce的排序,同时将GroupBy字段作 为reduce的key,在reduce阶段保存LastKey即可完成去重。
在这里插入图片描述
如果有多个distinct字段呢,如下面的SQL:
select dealid, count(distinct uid), count(distinct date) from order group by dealid;
实现方式有两种:

  • 1)如果仍然按照上面一个distinct字段的方法,即下图这种实现方式,无法跟据uid和date分别排序,也就无法通过LastKey去重,仍然需要在reduce阶段在内存中通过Hash去重。
    在这里插入图片描述
  • 2)第二种实现方式,可以对所有的distinct字段编号,每行数据生成n行数据,那么相同字段就会分别排序,这时只需要在reduce阶段记录LastKey即可去重。
    这种实现方式很好的利用了MapReduce的排序,节省了reduce阶段去重的内存消耗,但是缺点是增加了shuffle的数据量。
    需要注意的是,在生成reduce value时,除第一个distinct字段所在行需要保留value值,其余distinct数据行value字段均可为空。
    在这里插入图片描述
SQL转化为MapReduce的过程

了解了MapReduce实现SQL基本操作之后,我们来看看Hive是如何将SQL转化为MapReduce任务的,整个编译过程分为六个阶段:

  • Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree
  • 遍历AST Tree,抽象出查询的基本组成单元QueryBlock
  • 遍历QueryBlock,翻译为执行操作树OperatorTree
  • 逻辑层优化器进行OperatorTree变换,合并不必要的ReduceSinkOperator,减少shuffle数据量
  • 遍历OperatorTree,翻译为MapReduce任务
  • 物理层优化器进行MapReduce任务的变换,生成最终的执行计划

为了详细说明SQL翻译为MapReduce的过程,这里以一条简单的SQL为例,SQL中包含一个子查询,最终将数据写入到一张表中

FROM
(
  SELECT
    p.datekey datekey,
    p.userid userid,
    c.clienttype
  FROM
    detail.usersequence_client c
    JOIN fact.orderpayment p ON p.orderid = c.orderid
    JOIN default.user du ON du.userid = p.userid
  WHERE p.datekey = 20131118
) base
INSERT OVERWRITE TABLE `test`.`customer_kpi`
SELECT
  base.datekey,
  base.clienttype,
  count(distinct base.userid) buyer_count
GROUP BY  base.datekey, base.clienttype

SQL生成AST Tree
最终生成的AST Tree如下图右侧(使用Antlr Works生成,Antlr Works是Antlr提供的编写语法文件的编辑器),图中只是展开了骨架的几个节点,没有完全展开。
子查询1/2,分别对应右侧第1/2两个部分。
在这里插入图片描述
这里注意一下内层子查询也会生成一个TOK_DESTINATION节点。请看上面SelectStatement的语法规则,这个节点是在语法改写中特 意增加了的一个节点。原因是Hive中所有查询的数据均会保存在HDFS临时的文件中,无论是中间的子查询还是查询最终的结果,Insert语句最终会将 数据写入表所在的HDFS目录下。

Hive与mysql的差异

相同点

Hive采用了类SQL的查询语言HQL(hive query language),他们的操作语言类似,创建表、创建数据库、基本的增删改查。
除此之外,基本没有相同的点了。

不同点

除了hql语法相似外,内核、存储位置、能不能更新、有没有索引、执行的延迟、扩展性方面、数据规模都不一样。

  • Hive是为了数据仓库设计的。
  • 存储位置:Hive在Hadoop上;Mysql将数据存储在设备或本地系统中
  • 数据更新:Hive不支持数据的改写和添加,是在加载的时候就已经确定好了;数据库可以CRUD
  • 索引:Hive无索引,每次扫描所有数据,底层是MR,并行计算,适用于大数据量;MySQL有索引,适合在线查询数据
  • 执行:Hive底层是MapReduce;MySQL底层是执行引擎
  • 可扩展性:Hive:大数据量,扩展性很好;MySQL:相对就很少了
    所以Mysql可以做在线业务,而Hive只能做离线的分析业务

参考文献:https://www.cnblogs.com/csguo/p/7553022.html

发布了9 篇原创文章 · 获赞 0 · 访问量 62

猜你喜欢

转载自blog.csdn.net/yangbllove/article/details/105569900
今日推荐