INSERT OVERWRITE SELECT
本文介紹云原生數據倉庫 AnalyticDB MySQL 版表數據的高性能寫入方式INSERT OVERWRITE SELECT
,包括應用場景、功能原理、注意事項、語法和異步寫入應用。
功能原理
INSERT OVERWRITE SELECT
會先清空分區中的舊數據,再將新數據批量寫入到分區。
如果表是分區表,
INSERT OVERWRITE SELECT
只能覆蓋數據涉及到的分區,數據未涉及的分區不會被清空并覆蓋寫入。如果表是非分區表,
INSERT OVERWRITE SELECT
會清空整表的舊數據,并批量寫入新數據。
每個表的寫入任務串行執行,即單表寫入并發數為1,無法調整。為保證單任務寫入性能,防止集群負載過高,集群寫入任務并發數默認為2,不建議調整。
如有需要調整寫入并發數,請提交工單聯系技術支持,由技術支持評估調整。
特點與應用場景
INSERT OVERWRITE SELECT
的特點如下:
資源消耗大:高性能寫入
INSERT OVERWRITE SELECT
會消耗大量集群資源,建議在業務低峰期使用。批量可見:寫入任務完成前數據不可見,任務完成后該任務寫入的數據批量可見。
分區覆蓋:通過
INSERT OVERWRITE SELECT
寫入的分區數據會覆蓋目標表同一分區的數據。自動構建索引:寫入數據時同步構建索引,寫入任務完成,目標表就具備索引,可提升查詢性能。
INSERT OVERWRITE SELECT
常見的應用場景如下:
分區級數據寫入。
數據初始化(全量寫入)。
大批量數據寫入操作,不建議用于少量數據的寫入。
注意事項
請勿同時通過INSERT OVERWRITE SELECT
和實時寫入方式(INSERT INTO、REPLACE INTO、DELETE、UPDATE)向同一個表中寫入數據,否則實時寫入的數據會被丟棄。
語法
INSERT OVERWRITE table_name (column_name[,...])
select_statement
參數說明
table_name
:目標表的表名。column_name
:目標表的列名。select_statement
:SELECT語句。SELECT語句中每一列的數據類型需要與目標表每一列的數據類型相匹配。
如果SELECT語句中的列數比目標表的列數多,會寫入失敗;如果SELECT語句中的列數比目標表中的列數少,寫入數據時,目標表中多出的列會自動填充默認值,無默認值時值為NULL。
示例
示例數據
準備測試表和測試數據,用于測試下文覆蓋寫入的示例。
創建測試需要的源表
test_source
和目標表test_target
。CREATE TABLE test_source (a BIGINT, b BIGINT) DISTRIBUTED BY HASH(a);
CREATE TABLE test_target (a BIGINT, b BIGINT) DISTRIBUTED BY HASH(a) PARTITION BY VALUE(b) LIFECYCLE 10;
初始化源表
test_source
。INSERT INTO test_source VALUES (1,1); INSERT INTO test_source VALUES (1,2); INSERT INTO test_source VALUES (1,3); INSERT INTO test_source VALUES (2,1); INSERT INTO test_source VALUES (2,2); INSERT INTO test_source VALUES (2,3);
覆蓋寫入
初始化目標表
test_target
。INSERT OVERWRITE test_target SELECT * FROM test_source WHERE a = 1;
查詢
test_target
,得到如下結果。+-----+------+ |1 |1 | |1 |2 | |1 |3 | +-----+------+
對目標表
test_target
b=1的分區進行覆蓋寫入。INSERT OVERWRITE test_target (a,b) SELECT a,b FROM test_source WHERE a = 2 AND b = 1;
覆蓋寫入b=1的分區后,查詢
test_target
,得到如下結果。+-----+------+ |2 |1 | |1 |2 | |1 |3 | +-----+------+
對目標表
test_target
b=2和b=3的分區進行覆蓋寫入。INSERT OVERWRITE test_target SELECT * FROM test_source WHERE a = 2 AND b >= 2 AND b <= 3;
覆蓋寫入b=2和b=3的分區后,查詢
test_target
,得到如下結果。+-----+------+ |2 |1 | |2 |2 | |2 |3 | +-----+------+
異步寫入
提交任務
通常使用SUBMIT JOB
提交異步任務,由后臺調度執行。示例語句如下。
SUBMIT JOB
INSERT OVERWRITE adb_table
SELECT * FROM adb_external_table;
寫入調優
在寫入任務前增加Hint(/* direct_batch_load=true*/
)可以加速寫入任務。該Hint可以在節約大量資源的同時進一步提高寫入性能。示例語句如下。
/* direct_batch_load=true*/
SUBMIT JOB
INSERT OVERWRITE adb_table
SELECT * FROM adb_external_table;
僅3.1.5及以上內核版本支持/* direct_batch_load=true*/
。若使用后性能無明顯優化,可提交工單進行升級與優化。查看內核版本,請參見如何查看實例版本信息。
進度查詢
通過SUBMIT JOB
提交寫入任務后會返回job_id。以該job_id為條件查詢寫入任務的狀態,示例語句如下。
SHOW JOB STATUS WHERE job='<job_id>';
返回結果status列為SUCCEEDED,表示寫入任務完成。