在使用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>
.