一 严格模式
参数hive.mapred.mode=strict是hive的严格模式,严格模式下,是为了禁止用户做出某些查询,这些查询可能会带来不好的影响。严格模式下,一般来说,这儿有三种常见类型的查询:
1.1在一个分区表上,如果没有在WHERE条件中指明具体的分区,那么这是不允许的,换句话说,不允许在分区表上全表扫描。这种限制的原因是分区表通常会持非常大的数据集并且可能数据增长迅速,对这样的一个大表做全表扫描会消耗大量资源,必须要再WHERE过滤条件中具体指明分区才可以执行成功的查询。
hive(hadoop)> set hive.mapred.mode=strict;
hive(hadoop)> SELECT * FROM order;
FAILED:SemanticException [Error 10041]: No partition predicate found for Alias"order" Table "order"
Timetaken: 0.172 seconds, Fetched: 5 row(s)
hive(hadoop)> SELECT * FROM order WHERE age > 20;
FAILED:SemanticException [Error 10041]: No partition predicate found for Alias"order" Table "order"
1.2第二种是禁止执行有ORDERBY的排序要求但没有LIMIT语句的HiveQL查询。因为ORDERBY全局查询会导致有一个单一的reducer对所有的查询结果排序,如果对大数据集做排序,这将导致不可预期的执行时间,必须要加上limit条件才可以执行成功的查询。
hive(hadoop)> SELECT * FROM order WHERE code = 'CN' ORDER BY age;
FAILED:SemanticException 1:47 In strict mode, if ORDER BY is specified, LIMIT mustalso be specified. Error encountered near token 'age'
hive(hadoop)> SELECT * FROM order WHERE code = 'CN' ORDER BY age LIMIT 10;
这样就不会有问题
1.3第三种是禁止产生笛卡尔集。在JION接连查询中没有ON连接key而通过WHERE条件语句会产生笛卡尔集,需要改为JOIN...ON语句。
hive(hadoop)> SELECT * FROM emp e CROSS JOIN dept d WHERE d = 50;
FAILED:SemanticException [Error 10052]: In strict mode, cartesian product is notallowed. If you really want to perform the operation, sethive.mapred.mode=nonstrict
二 EXPLAIN
Hive提供了explain来显示查询执行计划。
USAGE:EXPLAIN [EXTENDED|DEPENDENCY] query;
2.1EXTENDED: 主要是会产生一些额外的跟operator有关的信息。
输出一下内容:
1查询的AST(抽象解析树)
2计划不同的阶段的依赖
3每一个阶段的描述
2.2DEPENDENCY
显示一些输入相关的一些属性值,比如表名,表类型,以及分区相关的信息
{"input_partitions":[{"partitionName":"hadoop@order@code=CN/range=16-20"},{"partitionName":"hadoop@order@code=CN/range=20-30"},{"partitionName":"hadoop@order@code=CN/range=21-30"},{"partitionName":"hadoop@order@code=CN/range=40-50"}],"input_tables":[{"tablename":"hadoop@order","tabletype":"MANAGED_TABLE"}]}
三 Fetch Task
FetchTask: 它不会运行MapReduce,直接从文件读取,这样的话就更加快一点。
那么在什么时候,才会触发FetchTask呢?
在hive中有一个参数hive.fetch.task.conversion=minimal
它有2个可选的值,minimal和more
相同点:对于以下查询,都会直接转化为FetchTask
#SELECT *
#SELECT 字段
#对分区列进行过滤
#简单的LIMIT n
不同点:
MORE还可以对TABLESAMPLE这种也会转化为FetchTask,,但是minimal不会转化
还有个问题,以下情况,是不会进行转化的:
# 输入来源只能来自一个表
SELECTe.empno,e.ename,e.job,d.dname,d.loc FROMemp e,dept d WHERE e.deptno = d.deptno;
比如数据来源多个表,需要跑MR
# 没有聚合操作和distinct
SELECTofrom,count(*) FROM order GROUP BY ofrom;
SELECTdistinct(oid) FROM order;
# 不能用于视图和JOIN
SELECT* FROM emp e JOIN dept d ON e.deptno = d.deptno;