并行执行,严格模式,Fetch抓取,本地模式

  • 一、查看执行计划(Explain)
  • 二、并行执行
  • 三、严格模式
  • 四、Fetch抓取
  • 五、本地模式


一、查看执行计划(Explain)

1)基本语法

EXPLAIN [EXTENDED | DEPENDENCY | AUTHORIZATION] query

(1)查看下面这条语句的执行计划

hive (default)> explain select * from emp;
hive (default)> explain select deptno, avg(sal) avg_sal from emp group by deptno;

hive 同步策略 hive 并行执行_大数据


(2)查看详细执行计划

hive (default)> explain extended select * from emp;
hive (default)> explain extended select deptno, avg(sal) avg_sal from emp group by deptno;

二、并行执行

Hive会将一个查询转化成一个或者多个阶段
这样的阶段可以是MapReduce阶段、抽样阶段、合并阶段、limit阶段。或者Hive执行过程中可能需要的其他阶段。
默认情况下,Hive一次只会执行一个阶段。不过,某个特定的job可能包含众多的阶段,而这些阶段可能并非完全互相依赖的,也就是说有些阶段是可以并行执行的,这样可能使得整个job的执行时间缩短。

通过设置参数hive.exec.parallel值为true,就可以开启并发执行。
不过,在共享集群中,需要注意下,如果 job 中并行阶段增多,那么集群利用率就会增加。

-- 打开任务并行执行,默认为false
set hive.exec.parallel=true;      
-- 同一个sql允许最大并行度,默认为8
set hive.exec.parallel.thread.number=16;
  • 建议在数据量大,子查询较多的时候使用。若数据量小,sql较为单一的时候开启,反而速度不如之前

三、严格模式

Hive可以通过设置防止一些危险操作:

1)分区表不使用分区过滤

hive.strict.checks.no.partition.filter设置为true时,对于分区表,除非 where语句 中含有分区字段过滤条件来限制范围,否则不允许执行。
换句话说,就是用户不允许扫描所有分区。
进行这个限制的原因是,通常分区表都拥有非常大的数据集,而且数据增加迅速。没有进行分区限制的查询可能会消耗巨大资源来处理这个表。

2)使用order by没有limit过滤

hive.strict.checks.orderby.no.limit设置为true时,对于使用了order by语句的查询,要求必须使用limit语句。
因为order by为了执行排序过程会将所有的结果数据分发到同一个Reducer中进行处理,强制要求用户增加这个LIMIT语句可以防止Reducer额外执行很长一段时间(开启了limit可以在数据进入到reduce之前就减少一部分数据)。

3)笛卡尔积

hive.strict.checks.cartesian.product设置为true时,会限制笛卡尔积的查询。
对关系型数据库非常了解的用户可能期望在 执行JOIN查询的时候不使用ON语句而是使用where语句,这样关系数据库的执行优化器就可以高效地将WHERE语句转化成那个ON语句。
不幸的是,Hive并不会执行这种优化,因此,如果表足够大,那么这个查询就会出现不可控的情况。

四、Fetch抓取

Fetch抓取是指,Hive中对某些情况的查询可以不必使用MapReduce计算。例如:SELECT * FROM emp;在这种情况下,Hive可以简单地读取emp对应的存储目录下的文件,然后输出查询结果到控制台。

hive.fetch.task.conversion默认是more,老版本 Hive 默认是 minimal(Minimal,查询分区表不走MR

  • none:执行任何查询都走mapreduce
  • minimal:执行(单个分区表)全局查找(select * )、字段查找、limit不走mapreduce,不加分区字段执行会走MR
  • more:执行(无论是否有分区表)全局查找(select * )、字段查找、limit都不走mapreduce
<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>

案例测试:

(1)把hive.fetch.task.conversion设置成minimal,然后执行查询语句。

hive (default)> set hive.fetch.task.conversion=minimal;
-- 会执行MR
hive (default)> select * from logs;
hive (default)> select logid from logs;
hive (default)> select logid from logs limit 3;
-- 不会执行MR
hive (default)> select * from logs where day='20200701';
hive (default)> select logid from logs where day='20200701';
hive (default)> select logid from logs where day='20200701' limit 3;

(2)把hive.fetch.task.conversion设置成more,如下查询方式不会执行mapreduce程序。

hive (default)> set hive.fetch.task.conversion=more;
-- 都不会执行MR
-- 不会执行MR
hive (default)> select * from logs;
hive (default)> select logid from logs;
hive (default)> select logid from logs limit 3;
-- 不会执行MR
hive (default)> select * from logs where day='20200701';
hive (default)> select logid from logs where day='20200701';
hive (default)> select logid from logs where day='20200701' limit 3;

五、本地模式

大多数的Hadoop Job是需要Hadoop提供的完整的可扩展性来处理大数据集的。不过,有时Hive的输入数据量是非常小的。
在这种情况下,为查询触发执行任务消耗的时间可能会比实际job的执行时间要多的多。
对于大多数这种情况,Hive可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显被缩短。

用户可以通过设置hive.exec.mode.local.auto的值为true,来让Hive在适当的时候自动启动这个优化。

-- 开启本地MR
set hive.exec.mode.local.auto=true;
-- 设置local mr的最大输入数据量,当输入数据量小于这个值时采用local  mr的方式,默认为134217728,即128M
set hive.exec.mode.local.auto.inputbytes.max=50000000;
-- 设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式,默认为4
set hive.exec.mode.local.auto.input.files.max=10;

案例测试:

(1)开启本地模式,并执行查询语句

hive (default)> set hive.exec.mode.local.auto=true; 
hive (default)> select * from emp cluster by deptno;

Time taken: 1.328 seconds, Fetched: 14 row(s)

(2)关闭本地模式,并执行查询语句

hive (default)> set hive.exec.mode.local.auto=false; 
hive (default)> select * from emp cluster by deptno;

Time taken: 20.09 seconds, Fetched: 14 row(s)