一、數據庫操作
-- 創建數據庫(默認路徑)
CREATE DATABASE IF NOT EXISTS myhive;-- 指定路徑創建數據庫
CREATE DATABASE myhive2 LOCATION '/myhive2';-- 查看數據庫信息
DESC DATABASE myhive;-- 刪除數據庫(強制刪除表)
DROP DATABASE myhive CASCADE;
二、表操作
1. 內部表 vs 外部表
-- 內部表(數據由Hive管理)
CREATE TABLE internal_table (id BIGINT, name STRING);-- 外部表(數據由HDFS管理,刪除表不刪數據)
CREATE EXTERNAL TABLE external_table (id INT)
LOCATION '/hive_table/external_table';
2. 分區表
-- 一級分區
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. 分桶表
CREATE TABLE bucketed_table (id INT)
CLUSTERED BY (id) INTO 4 BUCKETS;
三、數據操作
1. 數據加載
-- 從本地加載(復制文件)
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. 數據插入
-- 單條插入(不推薦,生成小文件)
INSERT INTO TABLE test VALUES (1, 'Alice');-- 批量插入(推薦)
INSERT OVERWRITE TABLE target_table
SELECT * FROM source_table;
四、查詢優化
1. 避免全表掃描
-- 分區過濾
SELECT * FROM partition_table WHERE month='202305';-- 分桶過濾
SELECT * FROM bucketed_table WHERE id % 4 = 0;
2. JOIN優化
-- 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. 數據傾斜處理
-- 分組聚合傾斜
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. 表結構查看
-- 查看表結構
DESC formatted my_table;-- 查看建表語句
SHOW CREATE TABLE my_table;
2. 性能調優參數
-- 啟用壓縮
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
)。
- 必須配置
-
數據傾斜排查
-- 檢查Key分布 SELECT key, COUNT(1) FROM table GROUP BY key ORDER BY COUNT(1) DESC LIMIT 10;