Hive查询-1

Posted 健哥说编程

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive查询-1相关的知识,希望对你有一定的参考价值。


查询

1、排序和聚集

1order 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设置的个数。

 

2sort 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);

查看里面的数据,可见为部分排序

 

Hive查询-1

3distribute 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文件中:

Hive查询-1


再示例,存在以下的数据结构:

 

Hive查询-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查询-1

 

指定一下分隔符号:

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);

查看数据,可见已经也根据温度进行了排序:

 

Hive查询-1

 

1、cluster by

如果distribute by sort by中所用的列相同,可以直接使用cluster by

 

2、连接

Hive简化了MapReduce的连接操作,这一点可以直接看到Hive的好处。

为了操作连接,现在我们准备数据:

UML表达的数据关系,就是一个人person有很多的汽车。

准备数据

Persons表:

 

Hive查询-1

[wangjian@hadoop31 ~]$ cat person.txt

P001Jack34

P002Mary36

P003Alex21

P100Jim28

P009Smith38

P004Stave32

 

Cars表:

 

[wangjian@hadoop31 ~]$ cat car.txt

C001BMW45P001

C100Benz50P002

C003Buick54P002

C004Audi23P100

C009TOTYTO18P009

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

C001BMW45P001

C100Benz50P002

C003Buick54P002

C004Audi23P100

C009TOTYTO18P009

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、外连接

1Left 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)

 

2right 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)

 

3full 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子句中出现。

 

6map端连接

对于小的表,在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的主要内容,如果未能解决你的问题,请参考以下文章

2021年大数据Hive:Hive查询语法

Hive查询-1

Hive_查询数据库

0823-5.15.1-HDFS慢导致Hive查询慢问题分析

使用 Hive 查询 Sqoop 到 MySQL

将 SQL 查询转换为 Hive 查询