Hive的視圖和索引

目錄

一、Hive Lateral View

1、基本介紹

2、Hive錶行轉列,列轉行以及Hive Lateral View在列轉行中的使用

二、Hive視圖

1、Hive視圖基本介紹

2、Hive視圖特點

3、Hive視圖的意義

4、Hive視圖的創建和刪除

5、視圖的使用

6、查詢所有的hive視圖 

三、Hive索引

1、Hive索引的實現原理

2、創建索引

3、使用索引

4、刪除索引

5、放棄索引


一、Hive Lateral View

1、基本介紹

Lateral View用於和UDTF函數(explode、split)結合來使用。 ​ 首先通過UDTF函數拆分成多行,再將多行結果組合成一個支持別名的虛擬表。主要解決在select使用UDTF做查詢過程中,查詢只能包含單個UDTF,不能包含其他字段、以及多個UDTF的問題。 ​

語法: ​

LATERAL VIEW udtf(expression) tableAlias AS columnAlias (',' columnAlias)

2、Hive錶行轉列,列轉行以及Hive Lateral View在列轉行中的使用

  • 表1:cityInfo

cityname

regionname

上海

四川北路

上海

虹梅路

上海

音樂學院

上海

徐家彙

上海

陸家嘴

上海

古北

北京

東四

北京

復興門

北京

新街口

北京

地安門

  • 表2:cityInfoSet

cityname

regionname

上海

四川北路,虹梅路,音樂學院,徐家彙,陸家嘴,古北

北京

地安門,復興門,東四,新街口

表1和表2的結構如上所示。

現在需要在 hive 中使用 Hql 語句對錶1和表2進行互相轉化。

(1)行轉列

使用的函數說明: 

concat_ws(string SEP,string array<String>):函數返回字符串連接後的結果,SEP表示各個字符串連接的分割符;

collect_set(col): 函數將col字段進行去重,併合併成一個數組。

表1=>表2 可以使用 hive 的內置函數 concat_ws() 和 collect_set()進行轉換,執行代碼如下所示:

select cityname,concat_ws(',',collect_set(regionname)) as address_set from cityInfo group by cityname;

(2)列轉行

使用到的函數

函數split(String str,String pat) 將字符串按照pat分割;

函數explode(array) 將數組中的元素拆分爲多行顯示。

表2=>表1 可以使用 hive 的內置函數 lateral view explode()進行轉化。代碼如下:

select cityname, regionname from cityInfoSet lateral view explode(split(address_set, ',')) aa as region;

 

二、Hive視圖

1、Hive視圖基本介紹

視圖是一個虛擬表,其內容由查詢定義。Hive 中的視圖和RDBMS中視圖的概念一致,都是一組數據的邏輯表示,本質上就是一條SELECT語句的結果集。視圖是純粹的邏輯對象,沒有關聯的存儲(Hive 3.0.0引入的物化視圖除外),當查詢引用視圖時,Hive可以將視圖的定義與查詢結合起來,例如將查詢中的過濾器推送到視圖中。

2、Hive視圖特點

(1)不支持物化視圖 ​;

(2)只能查詢,不能做加載數據操作 ​ ;

(3)視圖的創建,只是保存一份元數據,查詢視圖時才執行對應的子查詢 ​;

(4)view定義中若包含了ORDER BY/LIMIT語句,當查詢視圖時也進行了ORDER BY/LIMIT語句操作,view當中定義的優先級更高 ​ ;

(5)Hive視圖支持迭代視圖。

3、Hive視圖的意義

(1) 使用視圖使數據操作更簡便,相當於封裝了sql語句,類似於關係型數據庫中的存儲過程。

(2) 使用視圖,基表中的數據有了一定的安全性,使用視圖可以基於限制條件過濾數據,通過視圖限制數據訪問可以保護信息不被隨意查詢。

4、Hive視圖的創建和刪除

--創建視圖:
    CREATE VIEW [IF NOT EXISTS] [db_name.]view_name 
      [(column_name [COMMENT column_comment], ...) ]
      [COMMENT view_comment]
      [TBLPROPERTIES (property_name = property_value, ...)]
      AS SELECT ... ;
--查詢視圖:
    select colums from view;
--刪除視圖:
    DROP VIEW [IF EXISTS] [db_name.]view_name;

案例:

CREATE VIEW gal_view IF NOT EXISTS AS SELECT * FROM product1 p LEFT JOIN logistic l ON p.sku=l.lsku; 

5、視圖的使用

SELECT sku,price FROM gal_view;

6、查詢所有的hive視圖 

(1) show tables可以查看到新增的視圖

查看結構 :

(2) Hive的元數據信息一般存儲在mysql,Hive的視圖信息存儲在mysql hive數據庫中的 TBLS 表中,通過如下查詢語句可以查詢得到Hive中的所有視圖:

SELECT * FROM TBLS WHERE TBL_TYPE='VIRTUAL_VIEW';

結果:

三、Hive索引

hive的索引可以提高數據的檢索效率,避免全表掃描和資源浪費,對於含有group by的語句,對group by的字段添加索引可以提高查詢速度。

1、Hive索引的實現原理

在指定列上建立索引,會產生一張索引表(Hive的一張物理表),裏面的字段包括,索引列的值、該值對應的HDFS文件路徑、該值在文件中的偏移量。

在執行索引字段查詢時候,首先額外生成一個MR job,根據對索引列的過濾條件,從索引表中過濾出索引列的值對應的hdfs文件路徑及偏移量,輸出到hdfs上的一個文件中,然後根據這些文件中的hdfs路徑和偏移量,篩選原始input文件,生成新的split,作爲整個job的split,這樣就達到不用全表掃描的目的。

2、創建索引

創建索引的字段最好使用不更新的字段,以免頻繁重建索引數據。每次建立、更新數據後,都要重建索引以構建索引表。

現在有一張表名爲product1的表,需要將該表中的sku字段建立一個索引,案例:

create index test_index on table product1(sku)
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'
with deferred rebuild
in table product1_index;

create index test_index2 on table product1(sku) as 'bitmap' with deferred rebuild in table product1_index2;

 兩種創建方式 as 後表示兩種不同的索引處理器。

創建示例如下(這裏採用的bitmap索引處理器):

0: jdbc:hive2://cdh-001:10000/test> show tables;
+-----------+--+
| tab_name  |
+-----------+--+
| gal_view  |
| logistic  |
| product1  |
| stocks    |
+-----------+--+
4 rows selected (0.027 seconds)

//創建索引
0: jdbc:hive2://cdh-001:10000/test> create index test_index2 on table product1(sku) as 'bitmap' with deferred rebuild in table product1_index2;

0: jdbc:hive2://cdh-001:10000/test> show tables;
+------------------+--+
|     tab_name     |
+------------------+--+
| gal_view         | //這是之前創建的視圖
| logistic         |
| product1         |
| product1_index2  | //可以看到這裏多了一張索引表
| stocks           |
+------------------+--+
5 rows selected (0.033 seconds)

//重建索引生成索引數據(建立索引之後必須重建索引才能生效)
0: jdbc:hive2://cdh-001:10000/test> alter index test_index2 on product1 rebuild;

//創建完成後通過索引命令顯示索引
0: jdbc:hive2://cdh-001:10000/test> SHOW FORMATTED INDEX ON product1;
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+--+
|       idx_name        |       tab_name        |       col_names       |     idx_tab_name      |       idx_type        |        comment        |
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+--+
| idx_name              | tab_name              | col_names             | idx_tab_name          | idx_type              | comment               |
|                       | NULL                  | NULL                  | NULL                  | NULL                  | NULL                  |
|                       | NULL                  | NULL                  | NULL                  | NULL                  | NULL                  |
| test_index2           | product1              | sku                   | product1_index2       | bitmap                |                       |
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+--+

3、使用索引

hive默認不使用索引,需要設置才能使索引生效:

SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
SET hive.optimize.index.filter=true;
SET hive.optimize.index.filter.compact.minsize=0;

//執行查詢
select * from product1 where sku=272480720;

4、刪除索引

DROP INDEX IF EXISTS product1_index2 ON product1;

5、放棄索引

說了這麼多,但是我一般不使用索引,因爲在使用的過程中總是會出現很多奇怪的問題,就很煩,例如刪除索引時,經常出現執行成功,但是索引並沒有被刪除的情況,只有刪除原始數據表(案例中的product1),這個索引纔會被刪除,這在生產上一般是不被允許的。

但是對於數據量很大的表之間的關聯,對關聯字段建立索引還是有必要的,能夠較大程度上提高查詢速度,需要根據自身的業務和需求來確定是否使用索引。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章