hive sql里,帮我描述一个简单的sql的原理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hive sql里,帮我描述一个简单的sql的原理相关的知识,希望对你有一定的参考价值。

比如:select a.id,a.info,b.num from a join b on a.id=b.id where b.num>=10
表A两个字段:id和info;
表B两个字段:id和num
比如A表有3条数据:
id info
1 a
2 b
3 c
B表有4条数据:
id num
1 12
2 15
3 5
4 19
请求牛人清楚的写一下hadoop里map reduce的过程
比如先是扫描全表,where过滤了一批数,然后表是怎么map,怎么切分,最后怎么reduce的,最后输出
这么一道hive sql,怎么看它会转换为多少道MR作业?
job数,task数又怎么看,如果sql复杂了,我怎么判定是我sql哪个环节有问题呢,进而去优化sql。
本人对hadoop方面纯粹菜鸟,求大牛讲讲,感激不尽啊!
我的核心问题是 hadoop是怎么用map reduce来实现sql,原理是什么

select a.id,a.info,b.num from a join b on a.id=b.id and where b.num>=10

两个表做关联,首先where会过滤掉不需要的数据。
至于表怎么做map和reduce操作,在hive里的表是虚拟的,其实还是对hdfs文件进行操作,你可以在hdfs:///user/hive/warehouse路径下找到以表名来命名的文件,里面就是表的内容,可以执行-cat命令查看。所以,它的map操作很简单,就是按行读文件,然后会根据hive的默认分隔符\001对每行进行切分。切分完成后就会按照你SQL指定的逻辑进行合并,最后再输出成hdfs文件,只不过在hive里面看它是以表的形式展现的。

job数会在你执行sql语句之后紧接着有相应的日志记录,

Total MapReduce jobs = 2
Launching Job 1 out of 2
Number of reduce tasks not specified. Estimated from input data size: 2
In order to change the average load for a reducer (in bytes):
set hive.exec.reducers.bytes.per.reducer=<number>
In order to limit the maximum number of reducers:
set hive.exec.reducers.max=<number>
In order to set a constant number of reducers:

这样就是有两个job,正在执行第一个job。

Hadoop job information for Stage-1: number of mappers: 5; number of reducers: 2
而这个就会告诉你有多少个mapper和reducer。
像你写的这个sql有join操作,而且是hiveSQL里面最普通的join,那么一定会有reducer参与,如果数据量很大,比如上千万条记录,join就会特别慢,job进度就会一直卡在reduce操作。可以改成mapjoin或者sort merge bucket mapjoin。

其实hive效率不高,不适合实时查询,即使一个表为空,用hive进行查询也会很耗时,因为它要把sql语句翻译成MR任务。虽然简化了分布式编程,但是效率上就会付出代价。

你的这句sql应该会翻译成一个JOB来执行,就是简单地map和reduce。

mapreduce就是按行读文件,然后切分,合并,输出成文件。追问

谢谢呀,我把分数加到100分啦~
您能不能具体来讲讲呢:
join 相应的map reduce是怎么处理数据的,map join是怎么一步步处理的,以我给的那2个表为例吧。

追答

不好意思,最近工作太忙,没注意追问

最为普通的join策略,不受数据量的大小影响,也可以叫做reduce side join ,它是最没效率的一种join 方式,它由一个mapreduce job 完成.
首先将大表和小表分别进行map 操作, 在map shuffle 的阶段每一个map output key 变成了table_name_tag_prefix + join_column_value .即,每个map的outputkey 都变成了 列名 a.id或者b.id
然后每一个reduce 接受所有的map 传过来的split数据片 , 在reducce 的shuffle 阶段,它将map output key 前面的table_name_tag_prefix 给舍弃掉进行比较. 因为reduce 的个数可以由小表的大小进行决定,所以对于每一个节点的reduce 一定可以将小表的split 放入内存变成hashtable. 然后将大表的每一条记录进行一条一条的比较.

简单的说就是hash表,然后对每条记录进行匹配。

map join更好理解,不过最好是在两张表大小差距很大的情况下使用,map join对内存大小有要求,它要把小表放进内存中做成hash表,具体如下:
Map Join 的计算步骤分两步,将小表的数据变成hashtable广播到所有的map 端,将大表的数据进行合理的切分,然后在map 阶段的时候用大表的数据一行一行的去探测(probe) 小表的hashtable. 如果join key 相等,就写入HDFS.
map join 之所以叫做map join 是因为它所有的工作都在map 端进行计算.少了reduce,速度就会明显提高。

参考技术A 我不知道你问的什么我告诉你这个执行过程吧 !
1.FROM:对FROM子句中的前两个表执行笛卡尔积(Cartesian product)(交叉联接),生成虚拟表VT1
2.ON:对VT1应用ON筛选器。只有那些使<join_condition>为真的行才被插入VT2。
3.OUTER(JOIN):如果指定了OUTER JOIN(相对于CROSS JOIN 或(INNER JOIN),保留表(preserved table:左外部联接把左表标记为保留表,右外部联接把右表标记为保留表,完全外部联接把两个表都标记为保留表)中未找到匹配的行将作为外部行添加到 VT2,生成VT3.如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤 3,直到处理完所有的表为止。
4.WHERE:对VT3应用WHERE筛选器。只有使<where_condition>为true的行才被插入VT4.
5.GROUP BY:按GROUP BY子句中的列列表对VT4中的行分组,生成VT5.
6.CUBE|ROLLUP:把超组(Suppergroups)插入VT5,生成VT6.
7.HAVING:对VT6应用HAVING筛选器。只有使<having_condition>为true的组才会被插入VT7.
8.SELECT:处理SELECT列表,产生VT8.
9.DISTINCT:将重复的行从VT8中移除,产生VT9.
10.ORDER BY:将VT9中的行按ORDER BY 子句中的列列表排序,生成游标(VC10).
11.TOP:从VC10的开始处选择指定数量或比例的行,生成表VT11,并返回调用者。

(8)SELECT (9)DISTINCT (11)<Top Num><select list>
(1)FROM[left_table]
(3)<join_type>JOIN<right_table>
(2)ON<join_condition>
(4)WHERE<where_condition>
(5)GROUPBY<group_by_list>
(6)WITH<CUBE | RollUP>
(7)HAVING<having_condition>
(10)ORDERBY<order_by_list>追问

您好,我问的是我写的那段sql,hadoop是怎么用map reduce来实现,原理是什么,谢谢啦!

将 SQL 查询转换为 Hive 查询

【中文标题】将 SQL 查询转换为 Hive 查询【英文标题】:Convert SQL Query to Hive Query 【发布时间】:2019-07-12 11:36:48 【问题描述】:

有人可以帮我将此SQL 查询转换为hive 以获得相同的输出吗?

下面是查询

select count(email), 
       case substring_index(email,"@",-1) 
           when 'gmail.com'      then 'GMAIL' 
           when 'googlemail.com' then 'GMAIL' 
           when 'yahoo.com'      then 'YAHOO' 
           when 'ymail.com'      then 'YAHOO' 
            else 'OTHER' 
       END as DOMAIN  
   from DATA1 group by 2;

【问题讨论】:

我只是在一个表中有电子邮件,在执行上述查询后,我得到了低于输出.. 我也需要在 hive 中相同的输出。请建议我在 hive 中的查询。+----------------+--------+ |计数(电子邮件)|域名 | +--------------+--------+ | 3 |邮件 | | 2 |其他 | | 3 |雅虎 | +--------------+--------+ 欢迎来到 ***。请参考***.com/help/how-to-ask 和***.com/help/mcve。请使用您帖子的编辑选项并将相关代码 sn-ps 放在问题描述中。由于字符数限制和可读性较差,请勿在 cmets 部分发布问题详细信息。 【参考方案1】:
select count(email), 
       case split(email,'@')[1] 
           when 'gmail.com'      then 'GMAIL' 
           when 'googlemail.com' then 'GMAIL' 
           when 'yahoo.com'      then 'YAHOO' 
           when 'ymail.com'      then 'YAHOO' 
            else 'OTHER' 
       end as DOMAIN  
   from DATA1 
  group by 
    case substring_index(email,"@",-1) 
       when 'gmail.com'      then 'GMAIL' 
       when 'googlemail.com' then 'GMAIL' 
       when 'yahoo.com'      then 'YAHOO' 
       when 'ymail.com'      then 'YAHOO' 
       else 'OTHER' 
     end;

如果您希望 group by 2 工作,请阅读 group by position syntax 并相应地应用到您的配置单元版本。

【讨论】:

谢谢。我尝试在 hive 中用 split 函数替换子字符串。它正在工作 @Deepthi 满意请不要忘记采纳答案

以上是关于hive sql里,帮我描述一个简单的sql的原理的主要内容,如果未能解决你的问题,请参考以下文章

大数据系列之数据仓库Hive原理

HIVE_SQL转SparkSQL 简单示例

将 SQL 查询转换为 Hive 查询

hadoop中hive原理及安装

Hive SQL的底层编译过程详解

hive框架原理