Hive 系列(六)—— Hive 檢視和索引
一、檢視
1.1 簡介
Hive 中的檢視和 RDBMS 中檢視的概念一致,都是一組資料的邏輯表示,本質上就是一條 SELECT 語句的結果集。檢視是純粹的邏輯物件,沒有關聯的儲存 (Hive 3.0.0 引入的物化檢視除外),當查詢引用檢視時,Hive 可以將檢視的定義與查詢結合起來,例如將查詢中的過濾器推送到檢視中。
1.2 建立檢視
CREATE VIEW [IF NOT EXISTS] [db_name.]view_name -- 檢視名稱 [(column_name [COMMENT column_comment], ...) ] --列名 [COMMENT view_comment] --檢視註釋 [TBLPROPERTIES (property_name = property_value, ...)] --額外資訊 AS SELECT ...;
在 Hive 中可以使用 CREATE VIEW
建立檢視,如果已存在具有相同名稱的表或檢視,則會丟擲異常,建議使用 IF NOT EXISTS
預做判斷。在使用檢視時候需要注意以下事項:
檢視是隻讀的,不能用作 LOAD / INSERT / ALTER 的目標;
在建立檢視時候檢視就已經固定,對基表的後續更改(如新增列)將不會反映在檢視;
刪除基表並不會刪除檢視,需要手動刪除檢視;
檢視可能包含 ORDER BY 和 LIMIT 子句。如果引用檢視的查詢語句也包含這類子句,其執行優先順序低於檢視對應字句。例如,檢視
custom_view
指定 LIMIT 5,查詢語句為select * from custom_view LIMIT 10
建立檢視時,如果未提供列名,則將從 SELECT 語句中自動派生列名;
建立檢視時,如果 SELECT 語句中包含其他表示式,例如 x + y,則列名稱將以_C0,_C1 等形式生成;
CREATE VIEW IF NOT EXISTS custom_view AS SELECT empno, empno+deptno , 1+2 FROM emp;
1.3 檢視檢視
-- 檢視所有檢視: 沒有單獨檢視檢視列表的語句,只能使用 show tables show tables; -- 檢視某個檢視 desc view_name; -- 檢視某個檢視詳細資訊 desc formatted view_name;
1.4 刪除檢視
DROP VIEW [IF EXISTS] [db_name.]view_name;
刪除檢視時,如果被刪除的檢視被其他檢視所引用,這時候程式不會發出警告,但是引用該檢視其他檢視已經失效,需要進行重建或者刪除。
1.5 修改檢視
ALTER VIEW [db_name.]view_name AS select_statement;
被更改的檢視必須存在,且檢視不能具有分割槽,如果檢視具有分割槽,則修改失敗。
1.6 修改檢視屬性
語法:
ALTER VIEW [db_name.]view_name SET TBLPROPERTIES table_properties;
table_properties:
: (property_name = property_value, property_name = property_value, ...)
示例:
ALTER VIEW custom_view SET TBLPROPERTIES ('create'='heibaiying','date'='2019-05-05');
二、索引
2.1 簡介
Hive 在 0.7.0 引入了索引的功能,索引的設計目標是提高表某些列的查詢速度。如果沒有索引,帶有謂詞的查詢(如'WHERE table1.column = 10')會載入整個表或分割槽並處理所有行。但是如果 column 存在索引,則只需要載入和處理檔案的一部分。
2.2 索引原理
在指定列上建立索引,會產生一張索引表(表結構如下),裡面的欄位包括:索引列的值、該值對應的 HDFS 檔案路徑、該值在檔案中的偏移量。在查詢涉及到索引欄位時,首先到索引表查詢索引列值對應的 HDFS 檔案路徑及偏移量,這樣就避免了全表掃描。
+--------------+----------------+----------+--+
| col_name | data_type | comment |
+--------------+----------------+----------+--+
| empno | int | 建立索引的列 |
| _bucketname | string | HDFS 檔案路徑 |
| _offsets | array<bigint> | 偏移量 |
+--------------+----------------+----------+--+
2.3 建立索引
CREATE INDEX index_name --索引名稱
ON TABLE base_table_name (col_name, ...) --建立索引的列
AS index_type --索引型別
[WITH DEFERRED REBUILD] --重建索引
[IDXPROPERTIES (property_name=property_value, ...)] --索引額外屬性
[IN TABLE index_table_name] --索引表的名字
[
[ ROW FORMAT ...] STORED AS ...
| STORED BY ...
] --索引錶行分隔符 、 儲存格式
[LOCATION hdfs_path] --索引表儲存位置
[TBLPROPERTIES (...)] --索引表表屬性
[COMMENT "index comment"]; --索引註釋
2.4 檢視索引
--顯示錶上所有列的索引
SHOW FORMATTED INDEX ON table_name;
2.4 刪除索引
刪除索引會刪除對應的索引表。
DROP INDEX [IF EXISTS] index_name ON table_name;
如果存在索引的表被刪除了,其對應的索引和索引表都會被刪除。如果被索引表的某個分割槽被刪除了,那麼分割槽對應的分割槽索引也會被刪除。
2.5 重建索引
ALTER INDEX index_name ON table_name [PARTITION partition_spec] REBUILD;
重建索引。如果指定了 PARTITION,則僅重建該分割槽的索引。
三、索引案例
3.1 建立索引
在 emp 表上針對 empno
欄位建立名為 emp_index
,索引資料儲存在 emp_index_table
索引表中
create index emp_index on table emp(empno) as
'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'
with deferred rebuild
in table emp_index_table ;
此時索引表中是沒有資料的,需要重建索引才會有索引的資料。
3.2 重建索引
alter index emp_index on emp rebuild;
Hive 會啟動 MapReduce 作業去建立索引,建立好後檢視索引表資料如下。三個表字段分別代表:索引列的值、該值對應的 HDFS 檔案路徑、該值在檔案中的偏移量。
3.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;
3.4 檢視索引
SHOW INDEX ON emp;
四、索引的缺陷
索引表最主要的一個缺陷在於:索引表無法自動 rebuild,這也就意味著如果表中有資料新增或刪除,則必須手動 rebuild,重新執行 MapReduce 作業,生成索引表資料。
同時按照官方文件 的說明,Hive 會從 3.0 開始移除索引功能,主要基於以下兩個原因:
- 具有自動重寫的物化檢視 (Materialized View) 可以產生與索引相似的效果(Hive 2.3.0 增加了對物化檢視的支援,在 3.0 之後正式引入)。
- 使用列式儲存檔案格式(Parquet,ORC)進行儲存時,這些格式支援選擇性掃描,可以跳過不需要的檔案或塊。
ORC 內建的索引功能可以參閱這篇文章:Hive 效能優化之 ORC 索引–Row Group Index vs Bloom Filter Index
參考資料
- Create/Drop/Alter View
- Materialized views
- Hive 索引
- Overview of Hive Indexes
更多大資料系列文章可以參見 GitHub 開源專案: 大資料入門指南