一、表链接优化
- 小表在前大表在后
小表(放在join左侧)会优先加载到内存,大表会缓存起来
因为在 Reduce 阶段,位于 Join 操作符左边的表的内容会被加载进内存,载入条目较少的表 可以有效减少 OOM(out of memory)即内存溢出。
- 多表join的时候,使用相同的外键
三个表以上关联,只会产生一个MR job
- 尽量今早的过滤数据
尽量减少每个阶段的数据量,对于分区表要加分区,同时只选择需要用到的列
- 避免一个sql包含复杂逻辑,可以使用中间表来完成复杂程序
- Map Join 操作
Join 操作在 Map 阶段完成,不再需要Reduce,前提条件是需要的数据在 Map 的过程中可以访问到
INSERT OVERWRITE TABLE pv_users
SELECT /*+ MAPJOIN(pv) */ pv.pageid, u.age
FROM page_view pv
JOIN user u ON (pv.userid = u.userid);
用insert into替换union all如果union all的部分个数大于2,或者每个union部分数据量大,应该拆成多个insert into 语句,实际测试过程中,执行时间能提升50%。
二、列裁剪和分区裁剪
列裁剪
原因:减少读取开销,中间表开销和数据整合开销
参数配置:
hive.optimize.cp=true(默认值为真)
- 分区裁剪
设置读取的分区范围,
参数配置:
hive.optimize.pruner=true(默认值为真)
三、小数据集先进行本地模型
原因:查询出发执行任务消耗的时间 > 实际执行job的时间
参数配置:
set mapred.job.tracker=local
自动启动优化:
hive.exec.mode.local.auto = true
自定义参数配置:
- job的输入数据大小必须小于参数:hive.exec.mode.local.auto.inputbytes.max(默认128MB)
- job的map数必须小于参数:hive.exec.mode.local.auto.tasks.max(默认4)
- job的reduce数必须为0或者1
- 可用参数hive.mapred.local.mem(默认0)控制child的jvm使用的最大内存