1.Hive的严格模式
Hive提供了一个严格模式,可以防止用户执行那些产生意想不到的不好的影响的查询。
想想看在那么大的数据量的前提下,如果我们在分区上表上使用查找所有,或是使用了笛卡尔积查询数据等等不良情况,那得花费我们多少时间和资源成本,Hive在默认情况下会开启一种模式,叫做严格模式,来限制我们这些不良操作。
其中在hive-site.xml的配置文件中,设置了属性来进行全局的配置
对于全局的配置,我们可以修改这些属性,也可以采用临时会话的形式,使用set 属性=值的形式来进行修改,只不过只在当前会话有效。
使用了严格模式之后主要对以下3种不良操作进行控制:
1.分区表必须指定分区进行查询。
2.order by时必须使用limit子句。
3.不允许笛卡尔积。
2.Hive的动态分区
之前我们介绍过了分区表,并且查看了分区表的存储结构(分区表是目录),并且像分区表里面存储了数据。我们在进行存储数据的时候,都是明确的指定了分区。在这个过程中Hive也提供了一种比较任性化的操作,就是动态分区,不需要我们指定分区目录,Hive能够把数据进行动态的分发,例如2018年的数据,就让他进入2018年分区目录下,2017年的数据,就让他进入2017的目录下。使用动态分区的时候,我们需要将当前的严格模式设置成非严格模式,否则不允许使用动态分区
$hive>set hive.exec.dynamic.partition.mode=nonstrict//设置非严格模式
//设置动态分区的语法如下所示:
$hive>insert into t5 partition(country,province) select (包含分区的字段信息就可以) from orders;
//用到的相关的表
hive> CREATE TABLE t5(id int,price int) PARTITIONED BY (country string, province string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ;
//orders
1,24,china,sd
2,25,china,sd
3,26,china,sd
4,27,china,sd
5,28,china,sy
6,29,china,sy
7,30,china,sy
8,31,china,sy
9,32,china,sy
10,33,china,sy
11,34,china,sh
12,35,china,sh
13,24,china,sh
14,25,china,sh
15,26,china,sh
16,24,china,sh
如果当前模式是严格模式,则要求至少有一列的字段是静态的,且静态字段必须出现在最前面
$hive>insert into t5 partition(country=china,province) select (包含分区的字段信息就可以) from orders;
3.Hive的排序
与Mysql类似,Hive也提供了一些排序的语法,包括order by,sort by。
order by=MapReduce的全排序
sort by=MapReduce的部分排序
distribute by=MapReduce的分区
想想之前我们说过的大数据之Hadoop系列说的MapReduce的分区,排序,归并的过程。由于Hive在一些操作中会自动帮我们调用MapReduce来完成一些数据操作,会自动开启MapReduce操作,不用我们写Mapper和Reduce函数,如果我们使用上述的语法,是不是就是在自定义排序,自定义分区呢,是不是很简单的一句话就能够实现我们之前在大数据之Hadoop系列中的复杂的自定义分区,排序函数,是不是方便很多,舒服很多。
基本语法与MySql语法基本一致
selece .......from ...... order by 字段;//按照这个字段全排序
selece .......from ...... sort by 字段; //按照这个字段局部有序
selece 字段.....from ...... distribute by 字段;//按照这个字段分区
特别注意的是:
1.在上面的最后一个distribute by使用过程中,按照排序的字段要出现在最左侧也就是select中有这个字段,因为我们要告诉MapReduce你要按照哪一个字段分区,当然获取的数据中要出现这个字段了。类似于我们使用group by的用法,字段也必须出现在最左侧,因为数据要包含这个字段,才能按照这个字段分组,至于Hive什么时候会自行的开启MapReduce,那就是在使用聚合的情况下开启,使用select ...from ....以及使用分区表的selece ....from......where .....不会开启。
2.distribute by与sort by可以组合使用,但是distribute by要放在前边,因为MapReduce要先分区,后排序,再归并
语法如下:
select 字段a,........from .......distribute by字段a,sort by字段
如果distribute by与sort by使用的字段一样,则可以使用cluster by 字段替代:
select 字段a,........from .......cluster by 字段
4.Hive的事务
hive事务处理在>0.13.0之后支持行级事务。
---------------------------------------
1.所有事务自动提交。
2.只支持orc格式。
3.使用bucket表。
4.配置hive参数,使其支持事务。(只是设置了临时会话,只在当前对话生效,如要持久化,就在hive-site.xml中配置)
$hive>SET hive.support.concurrency = true;
$hive>SET hive.enforce.bucketing = true;
$hive>SET hive.exec.dynamic.partition.mode = nonstrict;
$hive>SET hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
$hive>SET hive.compactor.initiator.on = true;
$hive>SET hive.compactor.worker.threads = 1;
5.使用事务性操作
$>CREATE TABLE tx(id int,name string,age int) CLUSTERED BY (id) INTO 3 BUCKETS ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' stored as orc TBLPROPERTIES ('transactional'='true');
5.Hive的调优
Hive提供了多种的调优的手段,优化手段
//1使用explain查看查询计划
hive>explain select count(*) from customers ;
hive>explain extended select count(*) from customers ; //更加详细的信息
hive>explain select t.name , count(*) from (select a.name ,b.id,b.orderno from customers a ,orders b where a.id = b.cid) t group by t.name ;
//2.设置limit优化测,避免全部查询.
hive>set hive.limit.optimize.enable=true
//3本地模式
$hive>set mapred.job.tracker=local;//
$hive>set hive.exec.mode.local.auto=true//自动本地模式,测试
//4.严格模式,
$hive>set hive.mapred.mode=strict //1.分区表必须指定分区进行查询
//2.order by时必须使用limit子句。
//3.不允许笛卡尔积.
//5.设置MR的数量
hive> set hive.exec.reducers.bytes.per.reducer=750000000;//设置reduce处理的字节数。
//6.JVM重用
$hive>set mapreduce.job.jvm.numtasks=1//-1没有限制,使用大量小文件。
//7.数据倾斜.
$hive>SET hive.optimize.skewjoin=true;
$hive>SET hive.skewjoin.key=100000;
$hive>SET hive.groupby.skewindata=true;
补充:我们也可以通过如下手段来查看表的结构
desc 表;
desc formatted 表;//查看表的详细信息