一起聊一聊hive的索引最佳化。
大家好,我是球球,今天給大家聊聊hive的索引。
索引的作用
Hive從0.7.0版本開始加入了索引,目的是提高Hive表指定列的查詢速度。沒有索引的時候,Hive在執行查詢時需要載入整個表或者整個分割槽,然後處理所有的資料,但當在指定列上存在索引,再透過指定列查詢時,那麼只會載入和處理部分檔案。此外,同傳統關係型資料庫一樣,增加索引在提升查詢速度的同時,會額外消耗資源去建立索引和需要更多的磁碟空間儲存索引。Hive支援索引,但是Hive的索引與關係型資料庫中的索引並不相同,比如,Hive不支援主鍵或者外來鍵。
Hive索引可以建立在表中的某些列上,以提升一些操作的效率,例如減少MapReduce任務中需要讀取的資料塊的數量。
在可以預見到分割槽資料非常龐大的情況下,索引常常是優於分割槽的。
雖然Hive並不像事物資料庫那樣針對個別的行來執行查詢、更新、刪除等操作。它更多的用在多工節點的場景下,快速地全表掃描大規模資料。但是在某些場景下,建立索引還是可以提高Hive表指定列的查詢速度。(雖然這個效果還不是很好)
索引適用的場景
適用於不更新的靜態欄位。以免總是重建索引資料。每次建立、更新資料後,都要重建索引以構建索引表。
Hive索引的機制如下:
hive在指定列上建立索引,會產生一張索引表(Hive的一張物理表),裡面的欄位包括,索引列的值、該值對應的HDFS檔案路徑、該值在檔案中的偏移量;
v0.8後引入bitmap索引處理器,這個處理器適用於排重後,值較少的列(例如,某欄位的取值只可能是幾個列舉值)
因為索引是用空間換時間,索引列的取值過多會導致建立bitmap索引表過大。
但是,很少遇到hive用索引的,說明還是有缺陷or不合適的地方的,3.0 後hive去掉了索引.
hive索引的機制和原理
Hive的索引其實是一張索引表(Hive的物理表),在表裡面儲存索引列的值,該值對應的HDFS的檔案路徑,該值在資料檔案中的偏移量。當Hive透過索引列執行查詢時,首先透過一個MR Job去查詢索引表,根據索引列的過濾條件,查詢出該索引列值對應的HDFS檔案目錄及偏移量,並且把這些資料輸出到HDFS的一個檔案中,然後再根據這個檔案中去篩選原檔案,作為查詢Job的輸入。
優缺點
優點:
可以避免全表掃描和資源浪費 可以加快含有group by的語句的查詢速度 缺點:
Hive索引的使用過程比較繁瑣:
每次查詢時候都要先用一個job掃描索引表,如果索引列的值非常稀疏,那麼索引表本身也會非常大;
索引表不會自動rebuild,如果表有資料新增或刪除,那麼必須手動rebuild索引表資料;
索引應用
建立索引
create index index_name
on table base_table_name (col_name, ...)
as 'index.handler.class.name'
[with deferred rebuild]
[idxproperties (property_name=property_value, ...)]
[in table index_table_name]
[partitioned by (col_name, ...)]
[
[ row format ...] stored as ... | stored by ...
]
[location hdfs_path]
[tblproperties (...)]
[comment "index comment"]
as ‘index.handler.class.name’
指定索引處理器,這裡的一般使用org.apache.hadoop.hive.ql.index.compact.compactindexhandler
這個處理器。
[with deferred rebuild]
表明建立一個空索引,也就是說現在還不建立索引
[in table index_table_name]
索引儲存在哪個表中。
[idxproperties (property_name=property_value, …)]
索引的引數。一般使用idxproperties (‘creator’ = ‘me’,‘created_at’ = ‘some_time’)
,代表建立者和建立時間。
[partitioned by (col_name, …)]
[
[ row format …] stored as …
| stored by …
]
表明只對某個分割槽建立索引,若沒有該選項則表示對所有分割槽都建立索引,另外要注意的是index的分割槽索引預設是和表的分割槽一致的,也不能對檢視view建立索引。
例如:
create index test_index on table test(id)
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'
with deferred rebuild
in table test;
生成索引資料
剛建立完的Hive索引表是沒有資料的,需要生成索引資料
alter index test_index on test rebuild;
顯示索引
show index on t_travel_members_m;
重建資料
建立完索引之後 需要重建索引資料,會觸發一個mr job
alter index index_bill_id on t_travel_members_m rebuild;
使用索引
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;
刪除索引
drop index test_index on test;
總結
我們可以發現Hive的索引功能現在還相對較晚,提供的選項還較少。但是,索引被設計為可使用內建的可插拔的java程式碼來定製,使用者可以擴充套件這個功能來滿足自己的需求。當然不是說所有的查詢都會受惠於Hive索引。使用者可以使用EXPLAIN語法來分析HiveQL語句是否可以使用索引來提升使用者查詢的效能。像RDBMS中的索引一樣,需要評估索引建立的是否合理,畢竟,索引需要更多的磁碟空間,並且建立維護索引也會有一定的代價。使用者必須要權衡從索引得到的好處和代價。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024922/viewspace-2930581/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 聊一聊MySQL索引失效的問題MySql索引
- 聊一聊SQL最佳化SQL
- 面試官:聊一聊索引吧面試索引
- 聊一聊 JVM 的 GCJVMGC
- 聊一聊 RestTemplateREST
- 聊一聊 Javascript 中的 ASTJavaScriptAST
- 聊一聊 TLS/SSLTLS
- 聊一聊MySQL的直方圖MySql直方圖
- 聊一聊Redis的離線分析Redis
- 聊一聊MySQL的字符集MySql
- 聊一聊MySQL的儲存引擎MySql儲存引擎
- 聊一聊Jmeter的引數化JMeter
- 聊一聊Java的列舉enumJava
- 聊一聊遊戲的壓測遊戲
- 聊一聊橋接(JSBridge)的原理橋接JS
- 聊一聊Javascript中的Promise物件JavaScriptPromise物件
- 簡單聊一聊Vuex的原理Vue
- 聊一聊Greenplum與PostgreSQLSQL
- 聊一聊模板方法模式模式
- 聊一聊測試流程
- 聊一聊前端換膚前端
- 聊一聊session和cookieSessionCookie
- 聊一聊Spring Bean 的生命週期SpringBean
- 聊一聊 SQLSERVER 的行不能跨頁SQLServer
- [gRPC]來聊一聊gRPC的認證RPC
- 聊一聊RocketMQ的註冊中心NameServerMQServer
- 聊一聊Iterable與Iterator的那些事!
- 聊一聊泛型的可空性(kotlin)泛型Kotlin
- 聊一聊介面卡模式模式
- 聊一聊過度設計!
- 聊一聊裝飾者模式模式
- 聊一聊系統重構
- 聊一聊責任鏈模式模式
- Nginx-01-聊一聊 nginxNginx
- 聊一聊容器暫停退出
- 聊一聊隨機數安全隨機
- 聊一聊我認識的Linux系統Linux
- 聊一聊chkrookit的誤信和誤用