INSERT OVERWRITE ... 语句用于重写表或表的某些分区,将数据以原子性操作的方式写入。在分区替换时,会自动过滤不符合指定分区的导入数据。
INSERT OVERWRITE 语句执行时需获取分区锁或者表锁,每个分区或者表的写入任务串行执行,即单分区或者单表写入并发数为 1,无法调整。INSERT OVERWRITE 和实时写入方式(INSERT INTO、DELETE、UPDATE)向同一个表中写入数据,否则实时写入的数据会被丢弃。INSERT OVERWRITE TABLE table_name [ PARTITION (p1,... | *) ] [ (COLUMN [,...]) ] { VALUES ([,...] ), ([,...]) | QUERY }
参数说明
参数项 | 是否必填 | 配置说明 |
|---|---|---|
| 是 | 需要重写的目标表名。 |
| 否 | 指定需重写的分区(单分区 / 多分区);不指定则重写整表。 |
| 否 | 需要写入目标表的列,可以指定一个或多个列。指定多列时,需使用逗号分隔,最外层需要使用括号包裹。 |
| 是 | 需要写入的值列表,适用于少量固定数据的重写。与 |
| 是 | 需要写入的查询 |
本节演示了单分区键表场景下 INSERT OVERWRITE 的使用。
建表语句示例如下:
-- 1. 创建测试数据库(不存在则创建) CREATE DATABASE IF NOT EXISTS test_db; -- 2. 切换到测试数据库(后续操作默认在该库下) USE test_db; -- 3. 创建单分区键表 CREATE TABLE IF NOT EXISTS single_part_sales ( id Int32, sales_amount DECIMAL(10,2), dt String ) ENGINE = CnchMergeTree() ORDER BY (id) PARTITION BY (dt); -- 4. 插入初始数据 INSERT INTO single_part_sales VALUES (1, 150.50, '20240101'), (2, 200.00, '20240101'), (3, 300.25, '20240102'), (4, 180.75, '20240102'); -- 5. 查看初始数据(确认插入成功) SELECT * FROM single_part_sales; -- 6. 创建源表(存储待重写的新数据) CREATE TABLE IF NOT EXISTS source_sales ( id Int32, sales_amount DECIMAL(10,2), dt String ) ENGINE = CnchMergeTree() ORDER BY (id); -- 7. 向源表插入新数据(用于重写目标表) INSERT INTO source_sales VALUES (5, 250.00, '20240101'), (6, 320.50, '20240101');
单分区键 + SELECT 重写
-- 用 INSERT OVERWRITE + SELECT 重写目标表的 dt='20240101' 分区 INSERT OVERWRITE test_db.single_part_sales PARTITION ('20240101') SELECT id, sales_amount, dt FROM test_db.source_sales WHERE dt='20240101'; -- 查看重写后的数据(仅 dt='20240101' 分区被替换,dt='20240102' 不变) SELECT * FROM single_part_sales;
单分区键 + VALUES 重写
-- INSERT OVERWRITE + VALUES 重写 dt='20240102' 分区 INSERT OVERWRITE test_db.single_part_sales PARTITION ('20240102') VALUES (7, 400.00, '20240102'), (8, 150.25, '20240102'); -- 查看重写后的数据(dt='20240102' 分区被替换) SELECT * FROM single_part_sales;
单分区键 + 多分区重写
-- 同时重写两个分区 INSERT OVERWRITE test_db.single_part_sales PARTITION ('20240101', '20240102') VALUES (9, 500.00, '20240101'), (10, 350.75, '20240101'), (11, 200.50, '20240102'), (12, 450.00, '20240102'); -- 查看重写后的数据(两个分区均被替换) SELECT * FROM single_part_sales;
本节演示了多分区键表场景下 INSERT OVERWRITE 的使用。
建表语句示例如下:
-- 数据库使用场景一中创建的 test_db --- 1. 创建多分区键表 CREATE TABLE IF NOT EXISTS multi_part_sales ( id Int32, sales_amount DECIMAL(10,2), dt String, region String ) ENGINE = CnchMergeTree() ORDER BY (id) PARTITION BY (dt, region); -- 2. 插入初始数据 INSERT INTO multi_part_sales VALUES (1, 150.50, '20240101', 'north'), (2, 200.00, '20240101', 'north'), (3, 300.25, '20240101', 'south'), (4, 180.75, '20240102', 'north'); -- 3. 查看初始数据 SELECT * FROM multi_part_sales; -- 4. 创建源表 CREATE TABLE IF NOT EXISTS source_multi_sales ( id Int32, sales_amount DECIMAL(10,2), dt String, region String ) ENGINE = CnchMergeTree() ORDER BY (id); -- 5. 插入新数据 INSERT INTO source_multi_sales VALUES (5, 250.00, '20240101', 'north'), (6, 320.50, '20240101', 'north'), (7, 400.75, '20240101', 'south'), (8, 280.00, '20240102', 'north');
多分区键 + 多分区重写
INSERT OVERWRITE multi_part_sales PARTITION (('20240101', 'north'), ('20240101', 'south')) SELECT id, sales_amount, dt, region FROM test_db.source_multi_sales WHERE dt='20240101' AND region IN ('north', 'south'); -- 查看重写后的数据(仅指定的两个分区被替换,第三个分区不变) SELECT * FROM multi_part_sales;
多分区键 + 指定列重写
指定列时,需包含所有分区键列。
INSERT OVERWRITE multi_part_sales PARTITION (('20240102', 'north')) (dt, region, id, sales_amount) SELECT dt, region, id, sales_amount FROM test_db.source_multi_sales; -- 查看重写后的数据(仅目标分区的指定列被替换) SELECT * FROM multi_part_sales;
整表重写
-- 整表重写 INSERT OVERWRITE test_db.multi_part_sales SELECT id + 10 AS id, sales_amount * 1.1 AS sales_amount, dt, region FROM test_db.source_multi_sales; -- 查看整表重写结果(所有旧分区数据被替换为源表加工后的数据) SELECT * FROM multi_part_sales;