在使用Hive的時候,有時候只是想取表中某個分區的前幾條的記錄看下數據格式,比如一個很常用的查詢:
select * from foo where partition_column=bar limit 10;
Hive命令都要轉換為MapReduce任務去執行,但是因為啟動MapReduce需要消耗資源,然後速度還很慢(相比較於直接從本地文件中讀取而言),所以Hive對於查詢做了優化,對於某些查詢可以不啟動MapReduce任務的就儘量不去啟動MapReduce任務,而是直接從本地文件讀取。這種對數據基本沒什麼要求,隨便來點就行,既然如此為什麼不直接讀取本地存儲的數據作為結果集呢。
fetch task就是不啟動MapReduce,直接讀取本地文件輸出結果。
Hive有3個參數控制Fetch task, 對應2個優化器(優化那篇文章說了)
hive.fetch.task.conversion
hive.fetch.task.conversion.threshold
hive.fetch.task.aggr
對應優化器為SimpleFetchOptimizer和SimpleFetchAggregation
hive.fetch.task.conversion:這個屬性有三個可選的值:
none:關閉fetch task優化
minimal:只在select *、使用分區列過濾、帶有limit的語句上進行優化
more:在minimal的基礎上更加強大了,select不僅僅可以是*,還可以單獨選擇幾列,並且filter也不再局限於分區欄位,同時支持虛擬列(別名)
對於查詢所有列的情況,會使用fetch task:
如果是查詢部分列呢?
嘗試將hive.fetch.task.conversion設置為none,再查詢:
啟動了MapReduce任務。
hive.fetch.task.conversion.threshold:
在輸入大小為多少以內的時候fetch task生效,默認1073741824 byte = 1G。
hive.fetch.task.aggr:
對於沒有group by的聚合查詢,比如select count(*) from src,這種最終都會在一個reduce中執行,像這種查詢,可以把這個置為true將將其轉換為fetch task,這可能會節約一些時間。
對應優化器:SimpleFetchAggregation
總結!
hive源碼已經看了快一個月了,這種應該就能看完了。