在使用Hive的時候,有時候只是想取表中某個分區的前幾條的記錄看下數據格式,好比一個很經常使用的查詢:html
select * from foo where partition_column=bar limit 10;
這種對數據基本沒什麼要求,隨便來點就行,既然如此爲何不直接讀取本地存儲的數據做爲結果集呢。sql
Hive命令都要轉換爲MapReduce任務去執行,可是由於啓動MapReduce須要消耗資源,而後速度還很慢(相比較於直接從本地文件中讀取而言),因此Hive對於查詢作了優化,對於某些查詢能夠不啓動MapReduce任務的就儘可能不去啓動MapReduce任務,而是直接從本地文件讀取。apache
我的理解: fetch task = 不啓動MapReduce,直接讀取本地文件輸出結果。app
在hive-site.xml中有三個fetch task相關的值:oop
hive.fetch.task.conversionfetch
hive.fetch.task.conversion.threshold優化
hive.fetch.task.aggrthis
這個屬性有三個可選的值:xml
none:關閉fetch task優化htm
minimal:只在select *、使用分區列過濾、帶有limit的語句上進行優化
more:在minimal的基礎上更增強大了,select不單單能夠是*,還能夠單獨選擇幾列,而且filter也再也不侷限於分區字段,同時支持虛擬列(別名)
<property> <name>hive.fetch.task.conversion</name> <value>more</value> <description> Expects one of [none, minimal, more]. Some select queries can be converted to single FETCH task minimizing latency. Currently the query should be single sourced not having any subquery and should not have any aggregations or distincts (which incurs RS), lateral views and joins. 0. none : disable hive.fetch.task.conversion 1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only 2. more : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns) </description> </property>
對於查詢全部列的狀況,會使用fetch task:
若是是查詢部分列呢?
爲何查詢部分列也使用了Fetch Task?查看一下當前的set hive.fetch.task.conversion的值:
嘗試將hive.fetch.task.conversion設置爲none,再查詢:
啓動了MapReduce任務。
在輸入大小爲多少之內的時候fetch task生效,默認1073741824 byte = 1G。
<property> <name>hive.fetch.task.conversion.threshold</name> <value>1073741824</value> <description> Input threshold for applying hive.fetch.task.conversion. If target table is native, input length is calculated by summation of file lengths. If it's not native, storage handler for the table can optionally implement org.apache.hadoop.hive.ql.metadata.InputEstimator interface. </description> </property>
對於沒有group by的聚合查詢,好比select count(*) from src,這種最終都會在一個reduce中執行,像這種查詢,能夠把這個置爲true將將其轉換爲fetch task,這可能會節約一些時間。
<property> <name>hive.fetch.task.aggr</name> <value>false</value> <description> Aggregation queries with no group-by clause (for example, select count(*) from src) execute final aggregations in single reduce task. If this is set true, Hive delegates final aggregation stage to fetch task, possibly decreasing the query time. </description> </property>
.