hive語法和常用函數(shù)_第1頁
hive語法和常用函數(shù)_第2頁
hive語法和常用函數(shù)_第3頁
hive語法和常用函數(shù)_第4頁
hive語法和常用函數(shù)_第5頁
已閱讀5頁,還剩55頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

Hive是一個基于Hadoop分布式系統(tǒng)上的數(shù)據(jù)倉庫,最早是由Facebook公司開發(fā)的,Hive極大的推進了Hadoopecosystem在數(shù)據(jù)倉庫方面上的發(fā)展。

Facebook的分析人員中很多工程師比較擅長而SQL而不善于開發(fā)MapReduce程序,為此開發(fā)出Hive,并對比較熟悉SQL的工程師提供了一套新的SQL-like方言——HiveQL。

HiveSQL方言特別和MySQL方言很像,并提供了HiveQL的編程接口。HiveQL語句最終被Hive解析器引擎解析為MarReduce程序,作為job提交給JobTracker運行。這對MapReduce框架是一個很有力的支持。

Hive是一個數(shù)據(jù)倉庫,它提供了數(shù)據(jù)倉庫的部分功能:數(shù)據(jù)ETL(抽取、轉(zhuǎn)換、加載)工具,數(shù)據(jù)存儲管理,大數(shù)據(jù)集的查詢和分析能力。

由于Hive是Hadoop上的數(shù)據(jù)倉庫,因此Hive也具有高延遲、批處理的的特性,即使處理很小的數(shù)據(jù)也會有比較高的延遲。故此,Hive的性能就和居于傳統(tǒng)數(shù)據(jù)庫的數(shù)據(jù)倉庫的性能不能比較了。

Hive不提供數(shù)據(jù)排序和查詢的cache功能,不提供索引功能,不提供在線事物,也不提供實時的查詢功能,更不提供實時的記錄更性的功能,但是,Hive能很好地處理在不變的超大數(shù)據(jù)集上的批量的分析處理功能。Hive是基于hadoop平臺的,故有很好的擴展性(可以自適應(yīng)機器和數(shù)據(jù)量的動態(tài)變化),高延展性(自定義函數(shù)),良好的容錯性,低約束的數(shù)據(jù)輸入格式。

下面我們來看一下Hive的架構(gòu)和執(zhí)行流程以及編譯流程:

用戶提交的HiveQL語句最終被編譯為MapReduce程序作為Job提交給Hadoop執(zhí)行。

Hive的數(shù)據(jù)類型

Hive的基本數(shù)據(jù)類型有:TINYINT,SAMLLINT,INT,BIGINT,BOOLEAN,F(xiàn)LOAT,DOUBLE,STRING,TIMESTAMP(V0.8.0+)和BINARY(V0.8.0+)。

Hive的集合類型有:STRUCT,MAP和ARRAY。

Hive主要有四種數(shù)據(jù)模型(即表):(內(nèi)部)表、外部表、分區(qū)表和桶表。

表的元數(shù)據(jù)保存?zhèn)鹘y(tǒng)的數(shù)據(jù)庫的表中,當(dāng)前hive只支持Derby和MySQL數(shù)據(jù)庫。

內(nèi)部表:

Hive中的表和傳統(tǒng)數(shù)據(jù)庫中的表在概念上是類似的,Hive的每個表都有自己的存儲目錄,除了外部表外,所有的表數(shù)據(jù)都存放在配置在hive-site.xml文件的${hive.metastore.warehouse.dir}/table_name目錄下。

Java代碼

CREATE

TABLE

IF

NOT

EXISTS

students(user_no

INT,name

STRING,sex

STRING,

grade

STRING

COMMOT

'班級')COMMONT

'學(xué)生表'

ROW

FORMAT

DELIMITED

FIELDS

TERMINATED

BY

','

STORE

AS

TEXTFILE;

外部表:

外部表指向已經(jīng)存在在HadoopHDFS上的數(shù)據(jù),除了在刪除外部表時只刪除元數(shù)據(jù)而不會刪除表數(shù)據(jù)外,其他和內(nèi)部表很像。

Java代碼

CREATE

EXTERNAL

TABLE

IF

NOT

EXISTS

students(user_no

INT,name

STRING,sex

STRING,

class

STRING

COMMOT

'班級')COMMONT

'學(xué)生表'

ROW

FORMAT

DELIMITED

FIELDS

TERMINATED

BY

','

STORE

AS

SEQUENCEFILE

LOCATION

'/usr/test/data/students.txt';

分區(qū)表:

分區(qū)表的每一個分區(qū)都對應(yīng)數(shù)據(jù)庫中相應(yīng)分區(qū)列的一個索引,但是其組織方式和傳統(tǒng)的關(guān)系型數(shù)據(jù)庫不同。在Hive中,分區(qū)表的每一個分區(qū)都對應(yīng)表下的一個目錄,所有的分區(qū)的數(shù)據(jù)都存儲在對應(yīng)的目錄中。

比如說,分區(qū)表partitinTable有包含nation(國家)、ds(日期)和city(城市)3個分區(qū),其中nation=china,ds=20130506,city=Shanghai則對應(yīng)HDFS上的目錄為:

/datawarehouse/partitinTable/nation=china/city=Shanghai/ds=20130506/。

Java代碼

CREATE

TABLE

IF

NOT

EXISTS

students(user_no

INT,name

STRING,sex

STRING,

class

STRING

COMMOT

'班級')COMMONT

'學(xué)生表'

PARTITIONED

BY

(ds

STRING,country

STRING)

ROW

FORMAT

DELIMITED

FIELDS

TERMINATED

BY

','

STORE

AS

SEQUENCEFILE;

分區(qū)中定義的變量名不能和表中的列相同。

桶區(qū)表:

桶表就是對指定列進行哈希(hash)計算,然后會根據(jù)hash值進行切分數(shù)據(jù),將具有不同hash值的數(shù)據(jù)寫到每個桶對應(yīng)的文件中。

Java代碼

CREATE

TABLE

IF

NOT

EXISTS

students(user_no

INT,name

STRING,sex

STRING,

class

STRING

COMMOT

'班級',score

SMALLINT

COMMOT

'總分')COMMONT

'學(xué)生表'

PARTITIONED

BY

(ds

STRING,country

STRING)

CLUSTERED

BY(user_no)

SORTED

BY(score)

INTO

32

BUCKETS

ROW

FORMAT

DELIMITED

FIELDS

TERMINATED

BY

','

STORE

AS

SEQUENCEFILE;

內(nèi)部表和外部表的主要區(qū)別:

1)、內(nèi)部表創(chuàng)建要2步:表創(chuàng)建和數(shù)據(jù)加載,這兩個過程可以同步執(zhí)行。在數(shù)據(jù)加載的過程中,數(shù)據(jù)數(shù)據(jù)會移動到數(shù)據(jù)倉庫的目錄中;外部表的創(chuàng)建只需要一個步驟,表創(chuàng)建數(shù)據(jù)加載同時完成,表數(shù)據(jù)不會移動。

2)、刪除內(nèi)部表時,會將表數(shù)據(jù)和表的元數(shù)據(jù)一同刪除;而刪除外部表時,緊刪除表的元數(shù)據(jù)而不會刪除表數(shù)據(jù)。

在上一節(jié)《深入學(xué)習(xí)《ProgramingHive》:Hive的數(shù)據(jù)模型(表)》中,已經(jīng)學(xué)習(xí)過表的定義,接下來接著學(xué)習(xí)Hive的DDL操作。

復(fù)制表結(jié)構(gòu):Java代碼

CREATE

TABLE

IF

NOT

EXISTS

students2

LIKE

students;

查看表結(jié)構(gòu):Java代碼

DESCRIBE

TABLE

students;

刪除表:Java代碼

DROP

TABLE

students;

創(chuàng)建視圖:

Hive中的視圖(view)的概念和傳統(tǒng)數(shù)據(jù)庫中的表是相同的,是只讀的,目前還不支持不支持物化視圖。

如果在創(chuàng)建試圖后,再將基本表中被視圖引用的列修改,那么修改后的數(shù)據(jù)列將不會體現(xiàn)在視圖中;如果基本表被刪除或以不兼容的方式被修改,則查詢該視圖時會失敗。

Java代碼

CREATE

VIEW

IF

NOT

EXISTS

view_students

(user_no,name,score)

AS

SELECT

user_no,name,score

FROM

students;

刪除視圖:Java代碼

DROP

VIEW

view_students;

定制表存儲方式:Java代碼

CREATE

TABLE

IF

NOT

EXISTS

employees(

no

STRING,

name

STRING,

salary

FLOAT,

subordinates

ARRAY<STRING>,

deductions

MAP<STRING,FLOAT>,

address

STRUCT<street:STRING,district:STRING,city:STRING,province:STRING,ZIP:STRING>

)

ROW

FORMAT

DELIMITED

FIELDS

TERMINATED

BY

'\001'

COLLECTIN

ITEMS

TERMINATED

BY

'\002'

MAP

KEYS

TERMINATED

'\003'

LINES

TERMINATED

BY

'\n'

STORED

AS

INPUTFORMAT

'org.linkedin.haivvreo.AvroContainerInputFormat'

OUTPUTFORMAT

'org.linkedin.haivvreo.AvroContainerOutputFormat';

修改表結(jié)構(gòu):

1)、重命名表Java代碼

ALTER

TABLE

table_name

RENAME

TO

new_table_name;

只修改了表名,不會改變表結(jié)構(gòu)和數(shù)據(jù)存放的位置。

2)、修改列名、類型、位置及注釋Java代碼

CREATE

TABLE

IF

NOT

EXISTS

test(a

INT,b

STRING,c

FLOAT);//創(chuàng)建測試表

//修改列名

TABLE

test

CHANGE

a

a2

INT;

/*將a列的名字改為a2,并將其數(shù)據(jù)類型改為STRING,然后將之放在b列之后;修改

*

后的表結(jié)構(gòu)為:b

INT,a2

STRING,c

FLOAT

*/

ALTER

TABLE

test

CHANGE

a

a2

STRING

AFTER

b;

/*

*

將b列的名字改為b2,并將其數(shù)據(jù)類型由FLOAT改為DOUBLE,然后將之

*

放在第一列;修改后的表結(jié)構(gòu)為:

*

b2

DOUBLE,a

STRING,c

FLOAT

*/

ALTER

TABLE

test

CHANGE

b

b2

DOUBLE

FIRST;

列的改變只會修改Hive的元數(shù)據(jù),而不改變實際的數(shù)據(jù)。

用戶應(yīng)該確保元數(shù)據(jù)的定義和實際的數(shù)據(jù)結(jié)構(gòu)保持一致。

3)、增加新列Java代碼

ALTER

TABLE

test

ADD

COLOMNS(d

INT,e

STRING);

4)、改變表的數(shù)據(jù)存儲格式Java代碼

ALTER

TABLE

test

SET

FILEFORMAT

SEQUENCEFILE;

5)、添加分區(qū)PartitionJava代碼

ALTER

TABLE

students

ADD

PARTITION(ds

=

'2013-05-07',country

=

'china')

LOCATION

'/usr/test/data/test.txt';

6)、刪除分區(qū)PartitionJava代碼

ALTER

TABLE

students

DROP

PARTITION(ds

=

'2013-05-07',country

=

'china');

7)、創(chuàng)建函數(shù)Java代碼

CREATE

TEMPORARY

FIUNCTION

aFunc

as

class_name;

8)、刪除函數(shù)Java代碼

DROP

TEMPORARY

FIUNCTION

aFunc;

9)、顯示表Java代碼

SHOW

TABLES

students;

9)、顯示分區(qū)Java代碼

SHOW

PARTITIONS

students;

本節(jié)繼續(xù)討論HiveQL,Hive查詢語言,如何向Hive表中添加數(shù)據(jù),操縱數(shù)據(jù)和從表中將數(shù)據(jù)提取到文件系統(tǒng)。

之前已經(jīng)學(xué)習(xí)過Hive表的創(chuàng)建,本節(jié)主要關(guān)注向表中填充數(shù)據(jù),使表中有數(shù)據(jù)可供查詢。

先行創(chuàng)建本節(jié)要使用的表employees:Java代碼

CREATE

TABLE

employees

(

name

STRING,

salary

FLOAT,

subordinates

ARRAY<STRING>

COMMENT

'下屬',

deductions

MAP<STRING,FLOAT>

COMMENT

'扣費',

address

STRUT<street:STRING,city:STRING,state:STRING,zip:INT>

)

PARTITIONED

BY(country

STRING,state

STRING);

向管理表(非外部表)中加載數(shù)據(jù)

由于Hive沒有行級的insert,update和delete操縱,向表中加載數(shù)據(jù)的唯一方法就是“批量”加載數(shù)據(jù)。如下示例,想一個分區(qū)表中加載一批數(shù)據(jù):Java代碼

LOAD

DATA

LOCAL

INPATH

'${env:HOME}/calafornia-employees'

OVERWRITE

INTO

TABLE

employees

PARTITION

(country

=

'US',

state

=

'CA');

在加載數(shù)據(jù)之前首先要要保證已經(jīng)創(chuàng)建有符合條件的分區(qū)。在這個示例中,數(shù)據(jù)被加載后再Hive中的目錄為:

hdfs://master_server/user/hive/warehouse/mydb.db/employees/country=US/state=CA

這個示例需要注意幾點:

關(guān)鍵字OVERWRITE:加上該詞說明如果之前已經(jīng)箱蓋分區(qū)中加載過數(shù)據(jù)的話,則之前的數(shù)據(jù)會首先被“清洗掉”,然后才加載新數(shù)據(jù);如果沒有加關(guān)鍵字OVERWRITE的話,如:Java代碼

LOAD

DATA

LOCAL

INPATH

'${env:HOME}/calafornia-employees'

INTO

TABLE

employees

PARTITION

(country

=

'US',

state

=

'CA');

就不會將已有的數(shù)據(jù)清洗,而是直接在原有數(shù)據(jù)后邊追加新的數(shù)據(jù)。

關(guān)鍵字LOCAL:表明是從本地文件系統(tǒng)的文件夾中加載數(shù)據(jù),如果不加LOCAL關(guān)鍵字,則表明是從HDFS系統(tǒng)的文件夾中加載數(shù)據(jù):Java代碼

LOAD

DATA

INPATH

'${env:HOME}/calafornia-employees'

INTO

TABLE

employees

PARTITION

(country

=

'US',

state

=

'CA');

另外一點就是,對于要指定要加載的文件的路徑,指定一個文件夾是比較符合常規(guī)的,這要比每次單獨指定文件夾中的一個具體的文件要好,這樣Hive會一次把指定文件夾下的所有的位安全都拷貝到Hive倉庫中。

Hive在加載數(shù)據(jù)時并不會管要加載的數(shù)據(jù)是否和表定義模式相匹配,但是會驗證文件格式,比如說,在表中第一的保存的數(shù)據(jù)文件為SEQUENCEFILE,那么加載后的文件就必須為SEQUENCEFILE文件。

通過HiveQL查詢語句添加數(shù)據(jù)

INSERT語句可以讓用戶通過一個HiveQLQuery語句向Hive表中插入數(shù)據(jù)。看下面的一個示例(這里假設(shè)已經(jīng)定義過表staged_employees):Java代碼

INSERT

OVERWRITE

TABLE

employess

PARTTITION

(country

=

'US',state

=

'OR')

SELECT

*

FROM

staged_employees

se

WHERE

ty

=

'US'

AND

se.st

=

'OR';

OVERWRITE關(guān)鍵字,我們已經(jīng)討論過。但對于本示例來說,如果去掉OVERWRITE或用INTO替換掉,如:Java代碼

INSERT

INTO

TABLE

employess

PARTTITION

(country

=

'US',state

=

'OR')

SELECT

*

FROM

staged_employees

se

WHERE

ty

=

'US'

AND

se.st

=

'OR';

那么Hive就會將數(shù)據(jù)以“追加”的方式插入數(shù)據(jù)到employess表。

這個示例在一個場景中特別有用:數(shù)據(jù)已經(jīng)被保存在另外一個表中,如Hive的外部表,然后用戶想把某些數(shù)據(jù)做最終的保存到分區(qū)表中;或者從原有的數(shù)據(jù)源表中將數(shù)據(jù)保存成符合用的要求的不同的數(shù)據(jù)記錄的格式。

然而,如果staged_employees中數(shù)據(jù)特別大,有可能你需要執(zhí)行很多次這樣的插入查詢導(dǎo)入數(shù)據(jù)的話,比如說美國部分的數(shù)據(jù)就要執(zhí)行65次之多。Hive提供了另外一種INSERT語法,是你只掃描一次表就可以將數(shù)據(jù)插入到對應(yīng)的分區(qū)中:Java代碼

ROM

staged_employees

se

INSERT

INTO

TABLE

employess

PARTTITION

(country

=

'US',state

=

'OR')

SELECT

*

WHERE

ty

=

'US'

AND

se.st

=

'OR';

INSERT

INTO

TABLE

employess

PARTTITION

(country

=

'US',state

=

'CA')

SELECT

*

WHERE

ty

=

'US'

AND

se.st

=

'CA';

INSERT

INTO

TABLE

employess

PARTTITION

(country

=

'US',state

=

'IL')

SELECT

*

WHERE

ty

=

'US'

AND

se.st

=

'IL';

...

這種INSERT語法也可以一次插入多個表。

動態(tài)分區(qū)添加數(shù)據(jù)

就上例來說,好友一個問題,那就是如果有特別多的分區(qū)要創(chuàng)建的話,用戶不得不要寫許多HiveQL語句!幸運的是,Hive提供一個叫動態(tài)分區(qū)的功能,可以基于用戶的查詢參數(shù)推斷要創(chuàng)建的分區(qū)。通過與動態(tài)分區(qū)相比較,之前我們討論的分區(qū)插入數(shù)據(jù)被稱為靜態(tài)分區(qū)數(shù)據(jù)導(dǎo)入。

將上面的靜態(tài)分區(qū)作如下修改,就變成動態(tài)分區(qū)數(shù)據(jù)導(dǎo)入的示例:Java代碼

INSERT

OVERWRITE

TABLE

employees

PARTITION

(country,state)

SELECT

...,ty,se.st

FROM

staged_employees

se

對于本例來說,Hive會通過SELECT語句中最后兩列ty和se.st的值來決定employees表中的分區(qū)的key,contry和state。Hive在動態(tài)分區(qū)插入操作中特別強調(diào)源表的數(shù)據(jù)列的值和要插入分區(qū)的key的值的位置關(guān)系,而不是通過名字匹配,這也是為什么在staged_employees表中給國家和州定義不同的名字的原因。

假設(shè)staged_employees有100個國家和州的匹配對兒,那么執(zhí)行玩這個HiveQL語句后,employees就會有100個國家分區(qū)!

用戶也可以混合使用動態(tài)分區(qū)和靜態(tài)分區(qū)數(shù)據(jù)插入,如下例中,我們是用了一個靜態(tài)的country(US)和動態(tài)的州的值:Java代碼

INSERT

OVERWRITE

TABLE

employees

PARTITION

(country

=

'US',state)

SELECT

...,ty,se.st

FROM

staged_employees

se

WHERE

ty

=

'US';

要注意的是,必須要把靜態(tài)分區(qū)的key放在動態(tài)分區(qū)的key之前。

默認請情況下,動態(tài)分區(qū)插入的功能是被禁用的,當(dāng)被激活后,Hive默認會工作在“嚴格(strict)”模式下。在“嚴格(strict)”模式下,必須使用靜態(tài)分區(qū)和動態(tài)分區(qū)混合使用的方式,這主要是避免一些不好的數(shù)據(jù)查詢設(shè)計。

要使用動態(tài)模式,用戶首先要激活動態(tài)分區(qū)的一些參數(shù)設(shè)置:Java代碼

hive>

set

hibe.exec.dynamic.partition=true;

hive>

set

hibe.exec.dynamic.mode=nonstrict;

hive>

set

hibe.exec.max.dynamic.partitions.pernode=1000;

hive>

INSERT

OVERWRITE

TABLE

employees

PARTITION(country,state)

>

SELECT

...,ty,se.st

FROM

staged_employees

se;

nonstrict可以完全由用戶的查詢參數(shù)來動態(tài)創(chuàng)建所有的分區(qū)。

在一個HiveQL中創(chuàng)建表和加載數(shù)據(jù)

在Hive中,用戶可以完全使用一條語句創(chuàng)建表并同時加載數(shù)據(jù):Java代碼

CREATE

TABLE

ca_employees

AS

SELECT

name

salary,address

FROM

employees

WHERE

state

=

'CA';

這種方法特別適用于在一個大表中提取一個子數(shù)據(jù)集的場景,這種功能不適合外部表,因外外部表是在定義時直接給其制定一個數(shù)據(jù)文件的路徑。

導(dǎo)出數(shù)據(jù)

之前講的都是如何將數(shù)據(jù)加載到Hive表中,那么如何將表中數(shù)據(jù)導(dǎo)出表呢?用戶可以使用INSERT...DIRECTORY...語句導(dǎo)出數(shù)據(jù),示例如下:Java代碼

INSERT

OVERWRITE

LOCAL

DIRECTORY

'tmp/ca_employees'

SELECT

name,salary,address

FROM

employees

WHERE

state

=

'CA';

其中OVERWRITE和LOCAL的意義同上。

和加載數(shù)據(jù)一樣,用戶同樣可以在一個語句中將數(shù)據(jù)導(dǎo)出到多個文件夾:Java代碼

FROM

staged_employees

se

INSERT

OVERWRITE

DIRECTORY

'/tmp/or_employees'

SELECT

*

FROM

ty

=

'US'

AND

se.st

='OR'

INSERT

OVERWRITE

DIRECTORY

'/tmp/CA_employees'

SELECT

*

FROM

ty

=

'US'

AND

se.st

='CA'

INSERT

OVERWRITE

DIRECTORY

'/tmp/IL_employees'

SELECT

*

FROM

ty

=

'US'

AND

se.st

='IL'

前幾章已經(jīng)學(xué)習(xí)過Hive表的定義和數(shù)據(jù)操縱,本章我們開始學(xué)習(xí)HiveQL查詢。

SELECT...FROM...查詢

SELECT在SQL中是一個投影操作。讓我們從新來看之前定義過的分區(qū)表employees:Java代碼

CREATE

TABLE

employees

(

name

STRING,

salary

FLOAT,

subordinates

ARRAY<STRING>

COMMENT

'下屬',

deductions

MAP<STRING,FLOAT>

COMMENT

'扣費',

address

STRUT<street:STRING,city:STRING,state:STRING,zip:INT>

)

PARTITIONED

BY(country

STRING,state

STRING);

SELECT查詢:Java代碼

hive>

SELECT

name,salary

FROM

employees;

John

Doe

100000.0

Mary

Smith

80000.0

Todd

Jones

70000.0

Bill

King

60000.0

用戶也可以給FROM之后的表,視圖或子查詢起一個別名,如:Java代碼

hive>

SELECT

,e.salary

FROM

employees

e;

上面兩個HiveQL語句是相同的,給表起別名在JOIN操作中特別有用。

下面我們來看如何查詢employees表中的集合類型的數(shù)據(jù)。我們先看一下如何查詢ARRAY類型的數(shù)據(jù),如employees表的下屬“subordinates”Java代碼

hive>

SELECT

name,subordinates

FROM

employees;

John

Doe

["Mary

Smith","Todd

Jones"]

Mary

Smith

["Bill

King"]

Todd

Jones

[]

Bill

king

[]

再看MAP類型的查詢,如“deductions”:Java代碼

hive>

SELECT

name,deductions

FROM

employees;

John

Doe

{"Federal

Taxes":0.2,"State

Taxes":0.05,"Insurance":0.1}

Mary

Smith

{"Federal

Taxes":0.2,"State

Taxes":0.05,"Insurance":0.1}

Todd

Jones

{"Federal

Taxes":0.15,"State

Taxes":0.03,"Insurance":0.1}

Bill

King

{"Federal

Taxes":0.15,"State

Taxes":0.03,"Insurance":0.1}

再看STRUCT類型的查詢,如“address”:Java代碼

hive>

SELECT

name,address

FROM

employees;

John

Doe

{"Street":"1

Michign

Ave.","city":"Chicago","State":"IL","ZIP":60600}

Mary

Smith

{"Street":"100

Ontario

St.","city":"Chicago","State":"IL","ZIP":60601}

Todd

Jones

{"Street":"200

Chicago

Ave.","city":"Oak

Park","State":"IL","ZIP":60700}

Bill

King

{"Street":"300

Obscure

Dr.","city":"Obscuria","State":"IL","ZIP":60100}

接下來我們再看如何查看集合性屬性字段中的數(shù)據(jù):Java代碼

hive>

SELECT

name,subordinates[0],deductions["State

Taxes"],address.city

FROM

employees;

John

Doe

Mary

Smith

0.05

Chicago

Mary

Smith

Bill

King

0.05

Chicago

Todd

Jones

NULL

0.03

Oak

Park

Bill

King

NULL

0.03

Obscuria

使用正則表達式查詢符合條件的列

在Hive查詢中,用戶可以使用正則表達式查詢符合條件的列,下面的實例中就是使用正則表達式的使用用例,可以查詢到symbol列和所有以“price”開頭的列:Java代碼

hive>

SELECT

symbol,'price.*'

FROM

stocks;

AAPL

195.69

197.88

194.0

194.12

194.12

AAPL

192.63

196.0

190.85

195.46

195.46

AAPL

196.73

198.37

191.57

192.05

192.05

AAPL

195.17

200.2

194.42

199.23

199.23

AAPL

195.91

196.32

193.38

195.86

195.86

...

列計算

在HiveQL中,用戶不但可以從表中查詢某些列,還可以通過函數(shù)或數(shù)學(xué)表達式來計算列的值。例如,我們可以在employees表中查詢雇員的姓名,薪水,聯(lián)邦稅百分百及其他列的值:Java代碼

hive>

SELECT

upper(name),salary,deductions["Federal

Taxes"],

>

round(salary

*

(1

-

deductions["Federal

Taxes"]))

>

FROM

employees;

JOHN

DOE

100000.0

0.2

80000

MARY

SMITH

80000.0

0.2

64000

TODD

JONES

70000.0

0.15

59500

BILL

KING

60000.0

0.15

51000

Hive是使用JAVA寫的開源軟件,在函數(shù)或數(shù)學(xué)表達式來計算列的值時類型轉(zhuǎn)型和JAVA的轉(zhuǎn)型相同。

聚合函數(shù)

要在HiveQL查詢中使用聚合函數(shù),必須先將hive.map.aggr配置參數(shù)設(shè)置為true,舉例如下:Java代碼

hive>

SET

hive.map.aggr=true;

hibe>

SELECT

count(*),avg(salary)

FROM

employees;

但是將Java代碼

hive.map.aggr

設(shè)置為true會占用更多的內(nèi)存。

LIMIT

一次典型的HiveQL查詢可能會返回所有符合條件的數(shù)據(jù)記錄,但是LIMIT關(guān)鍵字可以限制返回的記錄的條數(shù):Java代碼

hive>

SELECT

upper(name),salary,deductions["Federal

Taxes"],

>

round(salary

*

(1

-

deductions["Federal

Taxes"]))

>

FROM

employees

>

LIMIT

2;

JOHN

DOE

100000.0

0.2

80000

MARY

SMITH

80000.0

0.2

64000

給列奇別名

Java代碼

hive>

SELECT

upper(name),salary,deductions["Federal

Taxes"]

AS

>

fed_taxes,round(salary

*

(1

-

deductions["Federal

Taxes"]))

AS

>

salary_minus_fed_taxes

>

FROM

employees

>

LIMIT

2;

JOHN

DOE

100000.0

0.2

80000

MARY

SMITH

80000.0

0.2

64000

子查詢

給列起別名特別適合與子查詢中的列,讓我們將上個查詢示例修改為子查詢的使用用例:Java代碼

hive>

FROM(

>

SELECT

upper(name),salary,deductions["Federal

Taxes"]

AS

>

fed_taxes,round(salary

*

(1

-

deductions["Federal

Taxes"]))

>

AS

salary_minus_fed_taxes

>

FROM

employees

>

)

e

>

SELECT

,e.salary_minus_fed_taxes

>

WHERE

e.salary_minus_fed_taxes

>

70000;

JOHN

DOE

100000.0

0.2

80000

CASE...WHEN...THEN語句

CASE...WHEN...THEN向標準的SQL語句中一樣使用在SELECT列中,對某一個列的返回值做判斷,示例如下:Java代碼

hive>

SELECT

name,salary,

>

CASE

>

WHEN

salary

<

50000.0

THEN

'low'

>

WHEN

salary

>=

50000.0

AND

salary

<

70000.0

THEN

'middle'

>

WHEN

salary

>=

70000.0

AND

salay

<

100000.0

THEN

'high'

ELSE

'very

high'

>

END

AS

bracket

FROM

employees;

John

Doe

100000.0

very

high

Mary

Smith

80000.0

high

Todd

Jones

70000.0

high

Bill

King

60000.0

middle

Boss

Man

200000.0

very

high

Fred

Finance

150000.0

very

high

Stcy

Accountant

60000.0

middle

WHERE過濾條件

SELECT決定返回哪些數(shù)據(jù)列,而WHERE決定返回那些符合條件的數(shù)據(jù):Java代碼

hive>

SELECT

name,salary,deductions["Federal

Taxes"],

>

salary

*

(1

-

deductions["Federal

Taxes"])

>

FROM

employees

>

WHERE

round(salary

*

(1

-

deductions["Federal

Taxes"]))

>

>

70000;

ohn

Doe

100000.0

0.2

80000.0

該示例有一個問題,那就是salary*(1-deductions["FederalTaxes"])分別在SELECT部分和WHERE部分都執(zhí)行了,性能上不是多優(yōu)化。那么,對salary*(1-deductions["FederalTaxes"])使用別名能否消除這種沖突呢?,不幸的是這是無效的:Java代碼

hive>

SELECT

name,salary,deductions["Federal

Taxes"],

>

salary

*

(1

-

deductions["Federal

Taxes"])

AS

>

salary_minus_fed_taxes

>

FROM

employees

>

WHERE

round(salary_minus_fed_taxes)

>

70000;

FAILED:Error

in

semantic

analysis:

Line

4:13

Invalid

table

alias

or

colomn

reference

'salary_minus_fed_taxes':

(possible

colomn

names

are:

name,salary,subordinates,deductions,address)

如錯誤信息中所說,用戶不能在WHERE部分中引用列的別名,那么我們是否可以使用其他辦法來消除這種沖突呢?答案是使用子查詢:Java代碼

hive>

SELECT

e.*

FROM

>

(SELECT

name,salary,deductions["Federal

Taxes"]

AS

ded,

>

salary

*

(1

-

deductions["Federal

Taxes"])

AS

>

salary_minus_fed_taxes

>

FROM

employees)

e

>

WHERE

round(salary_minus_fed_taxes)

>

70000;

浮點比較陷阱

在WHERE查詢條件中:在比較不同類型的數(shù)值(如FLOATvsDOUBLE)時,會引發(fā)浮點比較陷阱。

看下面的HiveQL語句,本來只想要查詢FederalTaxes>0.2,但是返回結(jié)果如下:Java代碼

hive>

SELECT

name,salary,deductions['Federal

Taxes']

>

FROM

employees

WHERE

deductions['Federal

Taxes']

>

0.2;

John

Doe

100000.0

0.2

Mary

Smith

80000.0

0.2

Boss

Man

200000.0

0.3

Fred

Finance

150000.0

0.3

我們發(fā)現(xiàn),為什不符合過濾條件(deductions('FederalTaxes')==0.2)的結(jié)果也返回了?!這就是浮點比較陷阱引發(fā)的。

那么如何來避免這個陷阱呢?那就要將0.2強制轉(zhuǎn)型了:Java代碼

hive>

SELECT

name,salary,deductions['Federal

Taxes']

>

FROM

employees

>

WHERE

deductions['Federal

Taxes']

>

cast(0.2

AS

FLOAT);

Boss

Man

200000.0

0.3

Fred

Finance

150000.0

0.3

LIKE和RLIKE

LIKE標識模糊查詢:Java代碼

hive>

SELECT

name,address.street

FROM

employees

WHERE

address.street

LIKE

'%Ave.';

John

Doe

1

Michigan

Ave.

Todd

Hones

200

Chicago

Ave.

hive>

SELECT

name,address.street

FROM

employees

WHERE

address.street

LIKE

'%Chi%';

Todd

Hones

200

Chicago

Ave.

RLIKE是使用正則表達式:Java代碼

hive>

SELECT

name,address.street

FROM

employees

>

WHERE

address.street

RLIKE

'.*(Chicago|Ontario).*';

Mary

Smith

100

Ontario

St.

Todd

Jones

200

Chicago

Ave.

GROUPBY

Hive的GROUPBY語句和傳統(tǒng)的SQL相同,經(jīng)常要和聚合函數(shù)一塊兒使用,我們再看一下stocks表的定義:Java代碼

CREAT

EXTENAL

TABLE

IF

NOT

EXISTS

stocks(

exchange

STRING,

symbol

STRING,

ymd

STRING,

price_open

FLOAT,

price_high

FLOAT,

price_low

FLOAT,

price_close

FLOAT,

volume

INT,

price_adj_close

FLOAT)

ROW

FORMAT

DELIMITED

FIELDS

TERMINATED

BY

','

LOCATION

'/data/stocks';

示例如下:Java代碼

hive>

SELECT

year(ymd),avg(price_close)

FROM

stocks

>

WHERE

exchange

=

'NASDAQ'

AND

symbol

=

'AAPL'

>

GROUP

BY

year(ymd);

1984

25.578625440597534

1985

20.193676221040867

1986

32.46102808021274

...

HAVING

Hive中的HAVING關(guān)鍵字和傳統(tǒng)SQL中的概念相同,是對分組后的結(jié)果再次過濾。使用HAVING可以避免GROUPBY后的子查詢:Java代碼

hive>

SELECT

year(ymd),avg(price_close)

FROM

stocks

>

WHERE

exchange

=

'NASDAQ'

AND

symbol

=

'AAPL'

>

GROUP

BY

year(ymd)

>

HAVING

avg(price_close)

>

50.0;

1987

53.88968399108163

1991

52.49553383386182

1992

54.80338610251119

2000

71.74892876261757

...

如果不使用HAVING,那么就要使用子查詢:Java代碼

hive>

SELECT

s2.year,s2.avg

FROM

>

(SELECT

year(ymd)

AS

year,avg(price_close)

AS

avg

FROM

stocks

>

WHERE

exchange

=

'NASDAQ'

AND

symbol

=

'AAPL'

>

GROUP

BY

year(ymd)

>

)

s2

>

WHERE

s2.avg

>

50.0

JION

Hive支持典型的SQLJION連接,但只支持等值連接。

Hive中的內(nèi)連接、左外連接、右外連接和全外連接和標準的SQL中的連接有相同的概念;但是在Hive中沒有IN、EXISTS關(guān)鍵字的使用,取代這兩個關(guān)鍵字的功能的是LEFTSEMI-JION,也是對InnerJION的性能上的加強優(yōu)化。

LEFTSEMI-JION

LEFTSEMI-JION和MySQL方言中的IN...EXISTS...結(jié)構(gòu)做同樣的事情:Java代碼

hive>

SELECT

s.ymd,s.symbol,s.price_close

>

FROM

stocks

s

LEFT

SEMI

JION

dividends

d

ON

s.ymd

=

d.ymd

AND

s.symbol

=

s.symbol;

...

1962-11-05

IBM

361.5

1962-08-07

IBM

373.25

1962-05-08

IBM

459.5

...

LEFTSEMIJOIN的限制是,JOIN子句中右邊的表只能在ON子句中設(shè)置過濾條件,在WHERE子句、SELECT子句或其他地方過濾都不行。

JION優(yōu)化

1)、將小表放在JION的左邊,Hive會將JION左邊的小表中的數(shù)據(jù)緩存起來,然后流式(stream)處理最后的表中的數(shù)據(jù),這可以提高HiveQL查詢的性能:Java代碼

SELECT

s.ymd,s.symbol,s.price_close,d.dividend

FROM

dividend

d

JION

stocks

s

ON

s.ymd

=

d.ymd

AND

s.symbol

=

d.symbol

WHERE

s.symbol

=

'AAPL';

幸運的是,用戶不用必須把要流式(stream)處理的表放在JION的右邊,Hive提供了一個“hint”機制來告訴查詢優(yōu)化器那個表中的數(shù)據(jù)需要被流式(stream)處理:Java代碼

SELECT

/*+

STREAMTABLE(s)

*/

s.ymd,s.symbol,s.price_close,d.dividend

FROM

stocks

s

JION

dividend

d

ON

s.ymd

=

d.ymd

AND

s.symbol

=

d.symbol

WHERE

s.symbol

=

'AAPL';

2)、在多個表做JION連接時,如果ON字句中的jionkeys都相同時,Hive會把多個table的jion連接編譯為一個MapReduceJob,否則一次jion連接會編譯成一個job。

3)、Map-SideJion:Hive提供Map端的jion連接操作,默認情況下是不支持該操作的,用戶必須強制告知查詢優(yōu)化器做Map端的Jion連接操作,這可以避免對結(jié)果進行大規(guī)模的笛卡爾集的操作,也可以減少數(shù)據(jù)的I/O流量:Java代碼

SELECT

/*+

MAPJION(s)

*/

s.ymd,s.symbol,s.price_close,d.dividend

FROM

stocks

s

JION

dividend

d

ON

s.ymd

=

d.ymd

AND

s.symbol

=

d.symbol

WHERE

s.symbol

=

'AAPL';

當(dāng)然做Map端的Jion連接操作之前,必須要設(shè)置一些參數(shù):Java代碼

hive>

SET

hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;;

hive>

SET

hive.optimize.bucketmapjion=true;

hive>

SET

hive.optimize.bucketmapjion.sortedmerge=true;

ORDERBY和SORTBY

ORDERBY和SQL方言中的orderby語句很像,會對所有的結(jié)果集做整體的排序操作,這就意味著所有的數(shù)據(jù)是通過一個Reducer處理的;對處理非常大的數(shù)據(jù)及來說,這會執(zhí)行非常長的處理時間。

Hive提供了一種局部排序的功能——SORTBY,只對每個Reducer處理的局部數(shù)據(jù)排序,也是一個本地排序,這也就是說每個Reducer處理后的數(shù)據(jù)是排序的,但對整體而言是無序的。Java代碼

SELECT

s.ymd,s.symbol,s.price_close

FROM

stocks

s

ORDER

BY

s.ymd

ASC,s.symbol

DESC;

SELECT

s.ymd,s.symbol,s.price_close

FROM

stocks

s

SORT

BY

s.ymd

ASC,s.symbol

DESC;

DISTRIBUTEBY

我們都知道,MapReduce模型是默認是通過hashPartitioner()函數(shù)將key/value的keys的hash值來數(shù)據(jù)分發(fā)到對應(yīng)的Reducers,DISTRIBUTEBY可以讓用戶來控制如何將key/value對分發(fā)到哪個Reducer。

這在大多數(shù)的情況下通常很有用。但是在默寫情況下,用戶可能需要有自己來決定按某一個字段來將數(shù)據(jù)分發(fā)到Reducers,如下所示:Java代碼

hive>

SELECT

s.ymd,s.symbol,s.price_close

FROM

stocks

s

>

DISTRIBUTE

BY

s.symbol

>

SORT

BY

s.symbol

ASC,s.ymd

ASC;

需要注意的是,DISTRIBUTEBY通常要和SORTBY使用,并且DISTRIBUTEBY必須使用在SORTBY之前。

CLUSTERBY

在上個使用DISTRIBUTEBY的示例中,由DISTRIBUTEBY按s.symbol字段將數(shù)據(jù)分發(fā)到相應(yīng)的Reducers,然后又SORTBY對Reducer最終輸出的數(shù)據(jù)按s.symbol和s.ymd做升序排序。

CLUSTERBY關(guān)鍵字可以起到DISTRIBUTEBY和SORTBY相同的功能:Java代碼

hive>

SELECT

s.ymd,s.symbol,s.price_close

FROM

stocks

s

>

CLUSTER

BY

s.symbol;

使用DISTRIBUTEBY和CLUSTERBY都可以起到對Reducers的輸出做并行排倒序。

類型轉(zhuǎn)化(Casting)

之前我們已經(jīng)學(xué)習(xí)過數(shù)據(jù)類型轉(zhuǎn)化的示例,如將一個數(shù)值轉(zhuǎn)化為FLOAT類型,轉(zhuǎn)換語法為cast(valueASTYPE),比如:Java代碼

SELECT

name,salary

FROM

employees

WHERE

cast(salary

AS

FLOAT)

<

100000.0

如果salary不能轉(zhuǎn)換成FLOAT類型的值的話,Hive會返回NULL。

轉(zhuǎn)換二進制類型的值

從Hive0.80開始,Hive開始支持二進制類型的值的轉(zhuǎn)換。將BINARY的值b轉(zhuǎn)換成STRING:Java代碼

SELECT

(2.0

*

cast(cast(b

AS

STRING)

AS

DOUBLE))

FROM

src;

同樣也可以講STRING類型轉(zhuǎn)換成BINARY類型。

采樣查詢

有些時候,用戶并不想對一個大數(shù)據(jù)集的數(shù)據(jù)做全部的分析處理,對于這種情況,Hive提供了對buckettable的采樣查詢功能:Java代碼

hive>

SELECT

*

FROM

numbers

TABLESAMPLE(BUCKET

1

OUT

OF

2

ON

number)s;

Hive中的桶下標是從1開始的。

Block數(shù)據(jù)塊數(shù)據(jù)采樣(BlockSampling)

Hive還提供了另外一種采樣的語法——Block數(shù)據(jù)塊數(shù)據(jù)采樣,用戶可以一個數(shù)據(jù)塊的數(shù)據(jù)行(rows)采樣:Java代碼

hive>

SELECT

*

FROM

numbersflat

TABLESAMPLE(0.1

PERCENT)

s;

UNIONALL

UNIONALL可以將兩個或多個子查詢的結(jié)果集合并到一塊兒,這就要就要合并的結(jié)果集必須要有相同的列數(shù),并且相對應(yīng)的列要有相匹配的類型:Java代碼

SELECT

log.ymd,log.level,log.message

FROM(

SELECT

l1.ymd,l1.level,l1.message,'log1'

AS

source

FROM

log1

l1

UNION

ALL

SELECT

l2.ymd,l3.level,l2.message,'log2'

AS

source

FROM

log2

l2

)

log

SORT

BY

log.ymd

ASC

Hive提供有限的索引功能,這不像傳統(tǒng)的關(guān)系型數(shù)據(jù)庫那樣有“鍵(key)”的概念,用戶可以在某些列上創(chuàng)建索引來加速某些操作,給一個表創(chuàng)建的索引數(shù)據(jù)被保存在另外的表中。

Hive的索引功能現(xiàn)在還相對較晚,提供的選項還較少。但是,索引被設(shè)計為可使用內(nèi)置的可插拔的java代碼來定制,用戶可以擴展這個功能來滿足自己的需求。

當(dāng)然不是說有的查詢都會受惠于Hive索引。用戶可以使用EXPLAIN語法來分析HiveQL語句是否可以使用索引來提升用戶查詢的性能。像RDBMS中的索引一樣,需要評估索引創(chuàng)建的是否合理,畢竟,索引需要更多的磁盤空間,并且創(chuàng)建維護索引也會有一定的代價。

用戶必須要權(quán)衡從索引得到的好處和代價。

創(chuàng)建索引

現(xiàn)在讓我們來為分區(qū)表employees創(chuàng)建一個索引。首先,然我們再回顧一下employees東側(cè)表定義:Java代碼

CREATE

TABLE

employees

name

STRING,

salary

FLOAT,

subordinates

ARRAY<STRING>,

deductions

MAP<STRING,FLOAT>,

address

STRUCT<street:STRING,city:STRING,state:STRING,zip:INT>

)

PARTITIONED

BY

(country

STRING,state

STRING);

接著讓我們看看如何為該表的contry分區(qū)創(chuàng)建索引:Java代碼

CREATE

INDEX

employees_index

ON

TABLE

employees

(country)

AS

'pact.CompactIndexHandler'

WITH

DEFERRED

REBUILD

IDXPROPERTIES

('creator'

=

'me','created_at'

=

'some_time')

IN

TABLE

employees_index_table

PARTITIONED

BY

(country,name)

COMMENT

'Employees

indexed

by

country

and

name.';

在本示例中,在employees上創(chuàng)建了名為employees_index的索引,索引數(shù)據(jù)存放在employees_index_table索引表中,WITHDEFERREDREBUILD表明創(chuàng)建一個空索引,可以在之后使用如下語句創(chuàng)建索引數(shù)據(jù):Java代碼

ALTER

INDEX

employees_index

ON

TABLE

employees

PARTITION(country

=

'US')

REBUILD;

PARTITIONEDBY表明只對某個分區(qū)創(chuàng)建索引,若沒有該選項則表示對所有分區(qū)都創(chuàng)建索引,另外要注意的是index的分區(qū)索引默認是和表的分區(qū)一致的,也不能對視圖VIEW創(chuàng)建索引。AS'pact.CompactIndexHandler'表示使用Apache的pact.CompactIndexHandler作為創(chuàng)建索引的handler,當(dāng)然也可以使用第三方的實現(xiàn)類或其他的實現(xiàn)類。

當(dāng)然也可以對其他字段創(chuàng)建索引。

Bitmap位圖索引

Hivev0.80添加了一個內(nèi)置的bitmap位圖索引。Bitmap位圖索引通常適用于只有少數(shù)不同值的列創(chuàng)建索引?,F(xiàn)在我們修改上一個索引示例為位圖索引:Java代碼

CREATE

INDEX

employees_index

ON

TABLE

employees

(country)

AS

'BITMAP'

WITH

DEFERRED

REBUILD

IDXPROPERTIES

('creator'

=

'me','created_at'

=

'some_time')

IN

TABLE

employees_index_table

PARTITIONED

BY

(country,name)

COMMENT

'Employees

indexed

by

country

and

name.';

重建索引

如果用戶在創(chuàng)建索引時指定WITHDEFERREDREBUILD關(guān)鍵字,那么開始時是一個空索引。我們在任何時候使用ALTERINDEX語句來創(chuàng)建或重建索引:Java代碼

ALTER

INDEX

employees_index

ON

TABLE

employees

PARTITION(country

=

'US')

REBUILD;

Hive沒有提供一個內(nèi)置的在數(shù)據(jù)變更時自動觸發(fā)創(chuàng)建索引的機制,故用戶需要自己通過ALTERINDEX語句來創(chuàng)建索引;另外,重建索引操作是一個原子操作,因此當(dāng)rebuild失敗時,已構(gòu)建的索引也無法使用。

查看索引

用戶可以查看某個表上的所有的索引:Java代碼

SHOW

FORMATTED

INDEX

ON

employees;

SHOW

FORMATTED

INDEXES

ON

employees;

刪除索引

在刪除一個索引的時候,也會同時刪除索引數(shù)據(jù)所在的表,如:Java代碼

DROP

INDEX

IF

EXISTS

employees_index

ON

TABLE

employees;

Hive使用的是Hadoop的文件系統(tǒng)和文件格式,比如TEXTFILE,SEQUENCEFILE等。

在Hive中對中間數(shù)據(jù)或最終數(shù)據(jù)數(shù)據(jù)做壓縮,是提高數(shù)據(jù)吞吐量和性能的一種手段。對數(shù)據(jù)做壓縮,可以大量減少磁盤的存儲空間,比如基于文本的數(shù)據(jù)文件,可以將文件壓縮40%或更多,同時壓縮后的文件在磁盤間傳輸和I/O也會大大減少;當(dāng)然壓縮和解壓縮也會帶來額外的CPU開銷,但是卻可以節(jié)省更多的I/O和使用更少的內(nèi)存開銷。

Hadoopjobs作業(yè),往往是I/O密集型的,而非CPU集型的。數(shù)據(jù)壓縮對I/O密集型的作業(yè)帶來大大的性能提升,但是如果用戶的jobs作業(yè)時CPU密集型的,那么在使用壓縮就會降低性能,這就要用戶對作業(yè)的類型做判斷,權(quán)衡是否要對數(shù)據(jù)做壓縮。

選擇合適的編解碼器

對數(shù)據(jù)做壓縮,可以最大程度的減少文件所需的磁盤空間和網(wǎng)絡(luò)I/O的開銷,但對數(shù)據(jù)做壓縮和解壓縮總會增加CPU的開銷,故最好對那些I/O密集型的作業(yè)使用數(shù)據(jù)壓縮——這樣的作業(yè)會有富余的CPU資源,或者對那些磁盤空間不富裕的系統(tǒng)。

Hadoop默認支持Gzip和BZip2的解壓縮方式,包括原生的linux解壓縮庫。Snappy壓縮在最近的Hive版本中才被添加的壓縮算法,如果您使用的是Hive不支持Snappy的話,用戶就要手動添加。過去經(jīng)常使用的是LZO壓縮算法。

那么,為什么要使用不同的壓縮算法呢?它們都有什么區(qū)別呢?BZip2有最高的壓縮比但也會帶來更高的CPU開銷,Gzip較BZip2次之;如果基于磁盤利用率和I/O考慮,這兩個壓縮算法都是比較有吸引力的算法。

LZO和Snappy算法有更快的解壓縮速度,如果在關(guān)注數(shù)據(jù)解壓多于磁盤利用率和I/O開銷的場景中,它們都是不錯的選擇。LZO和Snappy在壓縮數(shù)據(jù)上大致相當(dāng),但Snappy算法在解壓速度上要較LZO更快。

在選擇解壓縮算法時,另外一個比較重要的考慮就是壓縮格式是否是支持可分割的。Hadoop的會將大文件分割成HDFSblock(默認64MB)大小的splits分片,每個分片對應(yīng)一個Mapper程序。在這幾個壓縮算法中,只有BZip2和LZO提供block級的壓縮,而Gzip和Snappy則不支持。

Snappy壓縮算法時首選。

打開Hive(即由mappe產(chǎn)生的)中間數(shù)據(jù)文件的壓縮功能

HiveQL語句最終會被編譯成Hadoop的Mapreducejob,開啟Hive的中間數(shù)據(jù)壓縮功能,就是在MapReduce的shuffle階段對mapper產(chǎn)生的中間結(jié)果數(shù)據(jù)壓縮。在這個階段,優(yōu)先選擇一個低CPU開銷的算法。

可以通過參數(shù)ermediate來開啟和禁用該功能,默認情況下該值值為false,將之設(shè)置為true為激活中間數(shù)據(jù)壓縮功能:Java代碼

<property>

<name>ermediate</name>

<value>true</value>

<description>This

controls

whether

intermediate

files

produced

by

Hive

between

mutiple

map-redece

job

are

compressed.The

compression

codec

and

other

options

are

determined

from

hadoop

config

variable

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論