一、数据库操作
sql
-- 创建数据库(默认路径)
CREATE DATABASE IF NOT EXISTS myhive;
-- 指定路径创建数据库
CREATE DATABASE myhive2 LOCATION '/myhive2';
-- 查看数据库信息
DESC DATABASE myhive;
-- 删除数据库(强制删除表)
DROP DATABASE myhive CASCADE;
二、表操作
1. 内部表 vs 外部表
sql
-- 内部表(数据由Hive管理)
CREATE TABLE internal_table (id BIGINT, name STRING);
-- 外部表(数据由HDFS管理,删除表不删数据)
CREATE EXTERNAL TABLE external_table (id INT)
LOCATION '/hive_table/external_table';
2. 分区表
sql
-- 一级分区
CREATE TABLE partition_table (id INT, name STRING)
PARTITIONED BY (month STRING);
-- 多级分区
CREATE TABLE multi_partition (id INT)
PARTITIONED BY (year STRING, month STRING, day STRING);
-- 添加分区
ALTER TABLE partition_table ADD PARTITION (month='202305');
-- 删除分区
ALTER TABLE partition_table DROP PARTITION (month='202304');
-- 查看分区
SHOW PARTITIONS partition_table;
3. 分桶表
sql
CREATE TABLE bucketed_table (id INT)
CLUSTERED BY (id) INTO 4 BUCKETS;
三、数据操作
1. 数据加载
sql
-- 从本地加载(复制文件)
LOAD DATA LOCAL INPATH '/path/data.txt' INTO TABLE my_table;
-- 从HDFS加载(移动文件)
LOAD DATA INPATH '/hdfs/data.txt' INTO TABLE my_table;
-- 动态分区加载(需先开启动态分区)
SET hive.exec.dynamic.partition.mode=nonstrict;
INSERT INTO partition_table PARTITION (month)
SELECT id, name, month FROM source_table;
2. 数据插入
sql
-- 单条插入(不推荐,生成小文件)
INSERT INTO TABLE test VALUES (1, 'Alice');
-- 批量插入(推荐)
INSERT OVERWRITE TABLE target_table
SELECT * FROM source_table;
四、查询优化
1. 避免全表扫描
sql
-- 分区过滤
SELECT * FROM partition_table WHERE month='202305';
-- 分桶过滤
SELECT * FROM bucketed_table WHERE id % 4 = 0;
2. JOIN优化
sql
-- MapJoin(小表加载到内存)
SET hive.auto.convert.join=true;
SELECT /*+ MAPJOIN(small_table) */ *
FROM big_table JOIN small_table ON big_table.id = small_table.id;
3. 数据倾斜处理
sql
-- 分组聚合倾斜
SET hive.groupby.skewindata=true;
-- JOIN倾斜(随机打散)
SELECT *
FROM big_table a
JOIN (
SELECT *, RAND() AS rnd
FROM skewed_table
) b ON a.id = b.id AND b.rnd % 10 = 0;
五、元数据与配置
1. 表结构查看
sql
-- 查看表结构
DESC formatted my_table;
-- 查看建表语句
SHOW CREATE TABLE my_table;
2. 性能调优参数
sql
-- 启用压缩
SET hive.exec.compress.output=true;
SET mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
-- 合并小文件
SET hive.merge.mapfiles=true; -- Map输出合并
SET hive.merge.tezfiles=true; -- Tez输出合并
SET hive.merge.size.per.task=256000000; -- 合并后文件大小
六、经验总结
-
分区 vs 分桶
- 分区:按目录划分数据,适合范围过滤(如日期)。
- 分桶:按文件划分数据,适合JOIN和采样。
-
外部表使用场景
- 数据需被多组件共享(如Spark、Impala)。
- 避免误删数据(
DROP TABLE
不删HDFS数据)。
-
小文件处理
- 源头控制 :写入时用
INSERT OVERWRITE
替代INSERT INTO
。 - 事后合并 :
ALTER TABLE table_name CONCATENATE;
(仅ORC格式)。
- 源头控制 :写入时用
-
动态分区陷阱
- 必须配置
hive.exec.dynamic.partition.mode=nonstrict
。 - 避免分区数过多(超过
hive.exec.max.dynamic.partitions
)。
- 必须配置
-
数据倾斜排查
sql-- 检查Key分布 SELECT key, COUNT(1) FROM table GROUP BY key ORDER BY COUNT(1) DESC LIMIT 10;