1、索引
在指定列上建立索引,会产生一张索引表(Hive的一张物理表),里面的字段包括,索引列的值、该值对应的HDFS文件路径、该值在文件中的偏移量;
在执行索引字段查询时候,首先额外生成一个MR job,根据对索引列的过滤条件,从索引表中过滤出索引列的值对应的hdfs文件路径及偏移量,输出到hdfs上的一个文件中,然后根据这些文件中的hdfs路径和偏移量,筛选原始input文件,生成新的split,作为整个job的split,这样就达到不用全表扫描的目的。
1.1缺点:
- 使用较麻烦
- 数据更新,索引不自动更新, 需要手工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类查询
- 分区表但where没有指定分区条件
- order by但没有制定limit
- 限制笛卡尔积。注意:rdbms中,关联条件放where中是可以正常连接的,但Hive不行。
3.2调整mapper和reducer的个数
- 根据任务输入文件大小和每reducer处理的数据量决定的。
- 但是,部分map任务会生成远多于输入的数据量(关联?)
- 手工设定每作业的reducer个数:(集群总Reducer槽位个数*1.5)/并发的查询个数
3.3JVM重用:
- 重用的意义:JVM的创建是非常耗资源的动作,如果是小文件或task特别多,重用JVM,一个JVM跑多个task就特别有意义。
- 代价:重用情况下,Job不结束,该Job占用的Reducer插槽就不释放。
3.4动态分区调整
- 动态分区含义:insert 分区表 select *,col1,col2 from sourceTab 默认把select的末尾2字段当做分区键。
- 防止误操作导致超多的分区,可设定动态分区限制模式。误操作如错把时间戳当分区字段。
- 设置动态分区的最大个数、每个节点动态分区的最大个数。
3.4虚拟列:
有3个,类似Oracle的rowid、rownum:
- 文件名
- 记录在块内偏移量
- 记录在块内的行偏移量?