Hive 性能优化完整指南

Hive 作为大数据离线计算的核心工具,优化是每个数据开发者的必修课。本文总结了一套可落地的优化方案 ,覆盖 SQL 写法、参数调优、Join 优化、数据倾斜处理等场景。

一、SQL 写法优化(见效最快)

1. 分区裁剪

sql

:x: 错误:对分区字段用函数 WHERE SUBSTR(dt,1,7) = ‘2024-01’ – :white_check_mark: 正确:直接使用分区字段 WHERE dt >= ‘2024-01-01’ AND dt < ‘2024-02-01’

2. 避免 SELECT *

sql

:x: 错误:全表扫描 SELECT * FROM user_info – :white_check_mark: 正确:只取需要的列 SELECT user_id, name, age FROM user_info

3. 先过滤再 Join

sql

:white_check_mark: 正确:子查询先过滤 SELECT a.id, b.name FROM (SELECT * FROM big_table WHERE dt = ‘2024-01-01’) a JOIN small_table b ON a.id = b.id

二、Join 优化(核心)

1. MapJoin(小表广播)

sql

– 开启自动 MapJoin(默认 25MB) SET hive.auto.convert.join=true; SET hive.mapjoin.smalltable.filesize=25000000; – 或手动指定 SELECT /*+ MAPJOIN(small_table) */ * FROM large_table l JOIN small_table s ON l.key = s.key;

2. Bucket MapJoin

sql

– 要求:两张表按 Join 字段分桶,桶数成倍数 SET hive.optimize.bucketmapjoin=true; SELECT * FROM a JOIN b ON a.key = b.key;

三、核心参数调优

参数 作用 推荐值
mapreduce.job.reduces Reduce 并行度 200-500
mapreduce.map.memory.mb Map 内存 2048
mapreduce.reduce.memory.mb Reduce 内存 4096
hive.vectorized.execution.enabled 向量化执行 true
hive.exec.compress.intermediate 中间结果压缩 true
hive.exec.dynamic.partition.mode 动态分区模式 nonstrict
hive.merge.mapfiles 合并小文件 true
hive.merge.size.per.task 合并后文件大小 256000000

四、数据倾斜处理(难点)

1. 识别倾斜 Key

sql

SELECT key, COUNT(*) as cnt FROM table GROUP BY key ORDER BY cnt DESC LIMIT 20;

2. Group By 倾斜(两阶段聚合)

sql

– 加盐打散 SELECT key, SUM(partial_cnt) AS cnt FROM ( SELECT CASE WHEN key = ‘skew_key’ THEN CONCAT(key, ‘_’, CAST(RAND()10 AS INT)) ELSE key END AS key, COUNT() AS partial_cnt FROM table GROUP BY key ) t GROUP BY key;

3. Join 倾斜(拆分处理)

sql

– 非倾斜部分正常 Join SELECT * FROM big_table b JOIN small_table s ON b.key = s.key WHERE b.key NOT IN (‘skew1’, ‘skew2’) UNION ALL – 倾斜部分加随机数打散 SELECT * FROM ( SELECT b.*, CAST(RAND()10 AS INT) AS rand FROM big_table b WHERE b.key IN (‘skew1’, ‘skew2’) ) b JOIN ( SELECT s., CAST(RAND()*10 AS INT) AS rand FROM small_table s WHERE s.key IN (‘skew1’, ‘skew2’) ) s ON b.key = s.key AND b.rand = s.rand;

五、存储格式优化

格式 压缩比 查询速度 推荐场景
ORC :star::star::star::star::star: :star::star::star::star::star: 首选
Parquet :star::star::star::star::star: :star::star::star::star: Spark 生态
TextFile :star: :star: 临时数据

sql

CREATE TABLE table_name ( id BIGINT, name STRING ) STORED AS ORC TBLPROPERTIES (‘orc.compress’=‘SNAPPY’);

六、诊断命令速查

sql

– 查看执行计划 EXPLAIN SELECT …; – 查看表结构 DESC FORMATTED table_name; – 查看分区 SHOW PARTITIONS table_name; – 查看表大小(HDFS) dfs -du -h /user/hive/warehouse/db.db/table_name;

七、优化优先级总结

优先级 优化项 预期提升
1 分区裁剪 10-100 倍
2 MapJoin 5-20 倍
3 向量化执行 2-5 倍
4 数据倾斜处理 不稳定 → 稳定
5 存储格式 ORC 2-3 倍
6 参数调优 20-50%

:bulb: 一句话总结

分区 + MapJoin + 向量化 = 80% 的性能提升

3 个赞

感谢你的分享,谢谢大佬

2 个赞

这个问题涉及到key和SELECT的平衡,根据我的经验,适当调整table会有帮助。

1 个赞

不错不错

1 个赞

读写性能平衡是比较关键的

1 个赞

强的很