-- ===================================================================== -- @SparkSqlName: PAIMONA-D-SQL-{表名}-PARTITION -- @Version: 1.0 -- @Desc: 分区表操作模板 -- @TargetTables: {分区表名} -- @TargetDatabase: Paimon -- ===================================================================== -- ============================================================================ -- 分区表创建 -- ============================================================================ CREATE TABLE IF NOT EXISTS ${db_eda_env}.daily_partition_table ( id BIGINT COMMENT '主键ID', user_id STRING COMMENT '用户ID', amount DECIMAL(18,2) COMMENT '金额', etl_time TIMESTAMP COMMENT '数据加工时间' ) COMMENT '按日分区表' PARTITIONED BY (day_id STRING COMMENT '统计日期') STORED AS PARQUET; -- ============================================================================ -- 分区写入操作 -- ============================================================================ -- 1. 静态分区写入(指定分区值) INSERT OVERWRITE TABLE ${db_eda_env}.daily_partition_table PARTITION (day_id = '2026-05-09') SELECT id, user_id, amount, current_timestamp() AS etl_time FROM source_table WHERE day_id = '${day_id}'; -- 2. 动态分区写入(数据中包含分区值) -- 需要先设置动态分区模式 SET spark.sql.partitionOverwriteMode = dynamic; INSERT OVERWRITE TABLE ${db_eda_env}.daily_partition_table PARTITION (day_id) -- 动态分区字段 SELECT id, user_id, amount, current_timestamp() AS etl_time, day_id -- 数据中包含分区值 FROM source_table WHERE day_id BETWEEN '2026-05-01' AND '2026-05-09'; -- ============================================================================ -- 分区查询操作 -- ============================================================================ -- 3. 单分区查询 SELECT * FROM ${db_eda_env}.daily_partition_table WHERE day_id = '2026-05-09'; -- 4. 多分区查询 SELECT * FROM ${db_eda_env}.daily_partition_table WHERE day_id IN ('2026-05-01', '2026-05-02', '2026-05-03'); -- 5. 分区范围查询 SELECT * FROM ${db_eda_env}.daily_partition_table WHERE day_id >= '2026-05-01' AND day_id <= '2026-05-09'; -- 6. 最近 N 天分区查询(动态计算) SELECT * FROM ${db_eda_env}.daily_partition_table WHERE day_id >= date_format(date_sub(current_date(), 30), 'yyyy-MM-dd'); -- ============================================================================ -- 分区管理操作 -- ============================================================================ -- 7. 查看分区列表 SHOW PARTITIONS ${db_eda_env}.daily_partition_table; -- 8. 查看特定分区详情 DESCRIBE EXTENDED ${db_eda_env}.daily_partition_table PARTITION (day_id = '2026-05-09'); -- 9. 添加分区(手动创建空分区,部分表类型支持) ALTER TABLE ${db_eda_env}.daily_partition_table ADD IF NOT EXISTS PARTITION (day_id = '2026-05-10'); -- 10. 删除分区(清理历史数据) ALTER TABLE ${db_eda_env}.daily_partition_table DROP IF EXISTS PARTITION (day_id = '2026-01-01'); -- ============================================================================ -- 多分区字段操作 -- ============================================================================ -- 11. 多分区字段表创建 CREATE TABLE IF NOT EXISTS ${db_eda_env}.multi_partition_table ( id BIGINT, name STRING, amount DECIMAL(18,2), etl_time TIMESTAMP ) PARTITIONED BY (year_id STRING, month_id STRING) STORED AS PARQUET; -- 12. 多分区字段写入 INSERT OVERWRITE TABLE ${db_eda_env}.multi_partition_table PARTITION (year_id = '2026', month_id = '05') SELECT id, name, amount, current_timestamp() AS etl_time FROM source_table WHERE year_id = '2026' AND month_id = '05'; -- 13. 多分区字段动态写入 SET spark.sql.partitionOverwriteMode = dynamic; INSERT OVERWRITE TABLE ${db_eda_env}.multi_partition_table PARTITION (year_id, month_id) SELECT id, name, amount, current_timestamp() AS etl_time, year_id, month_id FROM source_table; -- ============================================================================ -- 分区数据清理 -- ============================================================================ -- 14. 清理指定分区数据 INSERT OVERWRITE TABLE ${db_eda_env}.daily_partition_table PARTITION (day_id = '2026-05-09') SELECT * FROM ${db_eda_env}.daily_partition_table WHERE day_id = '2026-05-09' AND status = 'valid'; -- 只保留有效数据 -- 15. 清理 N 天前分区(批量) -- 使用脚本或程序循环执行 -- ALTER TABLE xxx DROP PARTITION (day_id = '历史分区') -- ============================================================================ -- 分区最佳实践 -- ============================================================================ /* 1. 分区字段选择原则 - 查询高频过滤字段 - 数据量分布均匀的字段 - 时间字段最常用(day_id, month_id) 2. 分区粒度选择 - 日增量数据 → day_id 分区 - 月增量数据 → month_id 分区 - 大数据量 → 可细分到 hour_id 3. 分区数量控制 - 单表分区数建议 < 10000 - 过多分区影响元数据性能 4. 查询必须带分区过滤 - 避免:SELECT * FROM table(全表扫描) - 推荐:SELECT * FROM table WHERE day_id = '${day_id}' 5. 动态分区写入设置 - SET spark.sql.partitionOverwriteMode = dynamic; - 避免误覆盖其他分区 6. 分区数据清理 - 定期清理历史分区(如保留近90天) - 使用 ALTER TABLE DROP PARTITION */