1、索引

在指定列上建立索引,会产生一张索引表(Hive的一张物理表),里面的字段包括,索引列的值、该值对应的HDFS文件路径、该值在文件中的偏移量;
在执行索引字段查询时候,首先额外生成一个MR job,根据对索引列的过滤条件,从索引表中过滤出索引列的值对应的hdfs文件路径及偏移量,输出到hdfs上的一个文件中,然后根据这些文件中的hdfs路径和偏移量,筛选原始input文件,生成新的split,作为整个job的split,这样就达到不用全表扫描的目的。

1.1缺点:

  1. 使用较麻烦
  2. 数据更新,索引不自动更新, 需要手工rebuild

2、模式设计

结合Hive的特点,模式设计过程中注意:
	1)分区表:分区过细,产生大量目录和小文件,不适合HDSF的特性,还有注意namenode的内存极限(文件结构加载到内存)。
	2)复合结构与反规范化:与rdbms不同,hive的表不是严格的二维表格,是可以嵌套结合对象的,包括:array、map、struct。
	3)可以一次读取多个插入目标(Oracle有类似的)
	4)中间表加批次标记,可以支持多个批次同时跑或者调度和手工同时跑。确实!属于ETL设计的好方法。
	5)列存储:使用低候选值、宽表
	6)压缩:CPU换IO

3、调优

查看执行计划: explain [extended] Hiveql;

3.1严格模式:

hive.mapred.mode:strict,可以限制3类查询
  1. 分区表但where没有指定分区条件
  2. order by但没有制定limit
  3. 限制笛卡尔积。注意:rdbms中,关联条件放where中是可以正常连接的,但Hive不行。

3.2调整mapper和reducer的个数

  1. 根据任务输入文件大小和每reducer处理的数据量决定的。
  2. 但是,部分map任务会生成远多于输入的数据量(关联?)
  3. 手工设定每作业的reducer个数:(集群总Reducer槽位个数*1.5)/并发的查询个数

3.3JVM重用:

  1. 重用的意义:JVM的创建是非常耗资源的动作,如果是小文件或task特别多,重用JVM,一个JVM跑多个task就特别有意义。
  2. 代价:重用情况下,Job不结束,该Job占用的Reducer插槽就不释放。

3.4动态分区调整

  1. 动态分区含义:insert 分区表 select *,col1,col2 from sourceTab 默认把select的末尾2字段当做分区键。
  2. 防止误操作导致超多的分区,可设定动态分区限制模式。误操作如错把时间戳当分区字段。
  3. 设置动态分区的最大个数、每个节点动态分区的最大个数。

3.4虚拟列:

有3个,类似Oracle的rowid、rownum:

  1. 文件名
  2. 记录在块内偏移量
  3. 记录在块内的行偏移量?