Hive 作为大数据离线计算的核心工具,优化是每个数据开发者的必修课。本文总结了一套可落地的优化方案 ,覆盖 SQL 写法、参数调优、Join 优化、数据倾斜处理等场景。
一、SQL 写法优化(见效最快)
1. 分区裁剪
sql
–
错误:对分区字段用函数 WHERE SUBSTR(dt,1,7) = ‘2024-01’ –
正确:直接使用分区字段 WHERE dt >= ‘2024-01-01’ AND dt < ‘2024-02-01’
2. 避免 SELECT *
sql
–
错误:全表扫描 SELECT * FROM user_info –
正确:只取需要的列 SELECT user_id, name, age FROM user_info
3. 先过滤再 Join
sql
–
正确:子查询先过滤 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 |
|
|
首选 |
| Parquet |
|
|
Spark 生态 |
| TextFile | 临时数据 |
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% |
一句话总结
分区 + MapJoin + 向量化 = 80% 的性能提升