Hive查询-1
Posted 健哥说编程
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive查询-1相关的知识,希望对你有一定的参考价值。
查询
1、排序和聚集
1、order by 全排序
hive使用order by 实现全排序。
hive> insert overwrite local directory '${env:HOME}/a' select id,name,age from stud_unbucket order by id;
Order by 默认会忽略mapreduce.job.reduces设置的个数。
2、sort by部分排序
Sort by 为每一个reduce的输出生产一个排序的文件。
使用sort by 需要先设置set mapreduce.job.reduces=2;即reduces的个数。
hive> insert overwrite local directory '${env:HOME}/a' select id,name,age from stud_unbucket sort by (id);
查看里面的数据,可见为部分排序
3、distribute by指定保存
用于将指定的数据保存到指定的reduce输出中。
也需要将reduces个数数,设置成需要保存的成的文件的个数。
如:
Hive> set mapreduce.job.reduces=2;
以下将年龄%2取模以后结果,保存到不同的文件中去:
Hive>hive> insert overwrite local directory '${env:HOME}/a' select id,name,age from stud_unbucket distribute by(age%2);
执行完成以后,查看数据,可见,能被2整除的放到了0文件中,不能被2整除的放到了1文件中:
再示例,存在以下的数据结构:
现在需要将2001年和2002年的数据,分另导出到不同的数据文件中去,注意以下代码使用了substr/substring只取了年。
hive> insert overwrite local directory '${env:HOME}/b' select dt,temp from tempreture distribute by(substr(dt,0,4))
执行完成以后,查看输出,已经将相同的年写到了相同的输出文件中:
指定一下分隔符号:
hive> insert overwrite local directory '${env:HOME}/b'
row format delimited
fields terminated by '\t'
select dt,temp from tempreture distribute by(substr(dt,0,4)) sort by(temp asc);
查看数据,可见已经也根据温度进行了排序:
1、cluster by
如果distribute by 和sort by中所用的列相同,可以直接使用cluster by。
2、连接
Hive简化了MapReduce的连接操作,这一点可以直接看到Hive的好处。
为了操作连接,现在我们准备数据:
用UML表达的数据关系,就是一个人person有很多的汽车。
准备数据
Persons表:
[wangjian@hadoop31 ~]$ cat person.txt
P001Jack34
P002Mary36
P003Alex21
P100Jim28
P009Smith38
P004Stave32
Cars表:
[wangjian@hadoop31 ~]$ cat car.txt
C001BMW45万P001
C100Benz50万P002
C003Buick54万P002
C004Audi23万P100
C009TOTYTO18万P009
C008JETTY7万
创建表并导入数据
hive> create table person(
> id string,
> name string,
> age int
> )
> row format delimited
> fields terminated by '\t'
> stored as textfile;
OK
Time taken: 0.415 seconds
hive> load data local inpath '${env:HOME}/person.txt' into table person;
Loading data to table test.person
Table test.person stats: [numFiles=1, totalSize=79]
OK
Time taken: 1.25 seconds
hive> select * from person;
OK
P001Jack34
P002Mary36
P003Alex21
P100Jim28
P009Smith38
P004Stave32
Time taken: 0.388 seconds, Fetched: 6 row(s)
hive> create table car(
> id string,
> name string,
> price string,
> pid string
> )
> row format delimited
> fields terminated by '\t'
> stored as textfile;
OK
Time taken: 0.122 seconds
hive> load data local inpath '${env:HOME}/car.txt' into table car;
Loading data to table test.car
Table test.car stats: [numFiles=1, totalSize=124]
OK
Time taken: 0.679 seconds
hive> select * from car;
OK
C001BMW45万P001
C100Benz50万P002
C003Buick54万P002
C004Audi23万P100
C009TOTYTO18万P009
C008JETTY7万
Time taken: 0.142 seconds, Fetched: 6 row(s)
1、内连接
以下是查询某人拥有哪一部车。
hive> select p.id,p.name,p.age,c.id,c.name,c.price
> from person p join car c on(p.id=c.pid);
P001Jack34C001BMW45万
P002Mary36C100Benz50万
P002Mary36C003Buick54万
P100Jim28C004Audi23万
P009Smith38C009TOTYTO18万
Time taken: 38.23 seconds, Fetched: 5 row(s)
在hive中可以使用更多的的join连接更多的表,并使用and关联相同的字段。
更多连接的示例:
hive> select s.name,c.name from
> stud_bucket s join sc on (s.id=sc.sid)
> join course c on(sc.cid=c.id);
OK
JackJava
JackHadoop
MaryHadoop
Time taken: 31.867 seconds, Fetched: 3 row(s)
2、explain
可以使用explain查看hive的执行计划,部分代码如下:
hive> explain
> select s.name,c.name from
> stud_bucket s join sc on (s.id=sc.sid)
> join course c on(sc.cid=c.id);
OK
STAGE DEPENDENCIES:
Stage-7 is a root stage
Stage-5 depends on stages: Stage-7
Stage-0 depends on stages: Stage-5
...
还可以使用explain extended显示更多信息:
hive> explain extended
> select s.name,c.name from
> stud_bucket s join sc on (s.id=sc.sid)
> join course c on(sc.cid=c.id);
OK
ABSTRACT SYNTAX TREE:
...
3、将大表放到最后
Hive表的顺序很重要,一般将大表放到最后。(这应该是Map连接一个条件,因为小表将会在map端被缓存)。
4、外连接
1、Left outer join
将左表中的数据全部显示,如果没有匹配的值,则显示为NULL
hive> select p.name,c.name from person p left outer join car c on (p.id=c.pid);
OK
JackBMW
MaryBenz
MaryBuick
AlexNULL
JimAudi
SmithTOTYTO
StaveNULL
Time taken: 29.46 seconds, Fetched: 7 row(s)
2、right outer join
hive> select p.name,c.name from person p right outer join car c on (p.id=c.pid);
OK
JackBMW
MaryBenz
MaryBuick
JimAudi
SmithTOTYTO
NULLJETTY
Time taken: 28.456 seconds, Fetched: 6 row(s)
3、full outer join
hive> select p.name,c.name from person p full outer join car c on (p.id=c.pid);
OK
NULLJETTY
JackBMW
MaryBuick
MaryBenz
AlexNULL
StaveNULL
SmithTOTYTO
JimAudi
Time taken: 37.344 seconds, Fetched: 8 row(s)
5、半连接
考虑一个in的查询,如只查询在car表中出现的person id的记录:
hive> select * from person where id in(select pid from car);
OK
P001Jack34
P002Mary36
P100Jim28
P009Smith38
Time taken: 29.839 seconds, Fetched: 4 row(s)
现在可以使用left semi join实现上面的功能:
hive> select * from person p left semi join car c on(p.id=c.pid);
OK
P001Jack34
P002Mary36
P100Jim28
P009Smith38
Time taken: 29.352 seconds, Fetched: 4 row(s)
注意:使用left semi join时,右边即car的字段,只能在on子句中出现。
6、map端连接
对于小的表,在map端加载到缓存中进行执行。此时不需要reduce。但需要打开一个选项:
hive> set hive.optimize.bucketmapjoin=true;
然后:
再执行join即:
hive> select p.*,c.* from person p join car c on(p.id=c.pid);
以上是关于Hive查询-1的主要内容,如果未能解决你的问题,请参考以下文章