Insert
本文為您介紹如何使用INSERT語句向StarRocks中導入數(shù)據(jù)。
適用場景
如果僅導入幾條測試數(shù)據(jù),則可以使用INSERT INTO VALUES語句。
如果將源表中的數(shù)據(jù)進行ETL轉(zhuǎn)換并導入到一個新的StarRocks表中,則可以使用INSERT INTO SELECT語句。
如果僅覆蓋寫入幾條測試數(shù)據(jù),則可以使用INSERT OVERWRITE VALUES語句。
如果將源表中的數(shù)據(jù)進行ETL轉(zhuǎn)換并覆蓋寫入到一個新的StarRocks表中,則可以使用INSERT OVERWRITE SELECT語句。
源表可以是一張或多張內(nèi)部表或者外部表。目標表必須是StarRocks的內(nèi)表。
注意事項
StarRocks在執(zhí)行INSERT語句時,如果有數(shù)據(jù)不符合目標表格式(例如字符串超長等情況),INSERT操作默認執(zhí)行失敗。您可以通過設置會話變量
enable_insert_strict
為false
以確保INSERT操作過濾不符合目標表格式的數(shù)據(jù),并繼續(xù)執(zhí)行。頻繁使用INSERT語句導入小批量數(shù)據(jù)會產(chǎn)生過多的數(shù)據(jù)版本,從而影響查詢性能,因此不建議您頻繁使用INSERT語句導入數(shù)據(jù)或?qū)⑵渥鳛樯a(chǎn)環(huán)境的日常例行導入任務。如果您的業(yè)務場景需要流式導入或者小批量多次導入數(shù)據(jù),建議使用Stream Load或者Routine Load的方式進行導入。
執(zhí)行INSERT OVERWRITE語句后,系統(tǒng)將為目標分區(qū)創(chuàng)建相應的臨時分區(qū),并將數(shù)據(jù)寫入臨時分區(qū),最后使用臨時分區(qū)原子替換目標分區(qū)來實現(xiàn)覆蓋寫入。其所有過程均在Leader FE節(jié)點執(zhí)行。因此,如果Leader FE節(jié)點在覆蓋寫入過程中發(fā)生宕機,將會導致該次INSERT OVERWRITE導入失敗,其過程中所創(chuàng)建的臨時分區(qū)也會被刪除。
基本語法
INSERT { INTO | OVERWRITE } [db_name.]<table_name>
[ PARTITION (<partition_name> [, ...] ) ]
[ TEMPORARY PARTITION (<temporary_partition_name> [, ...] ) ]
[ WITH LABEL <label>]
[ (<column_name>[, ...]) ]
{ VALUES ( { <expression> | DEFAULT } [, ...] ) | <query> }
參數(shù)說明如下表所示。
參數(shù) | 說明 |
INTO | 將數(shù)據(jù)追加寫入目標表。 |
OVERWRITE | 將數(shù)據(jù)覆蓋寫入目標表。 |
table_name | 導入數(shù)據(jù)的目標表名稱。填寫形式為db_name.table_name。 |
PARTITION | 導入的目標分區(qū)。必須是目標表中存在的分區(qū),多個分區(qū)名稱用逗號(,)分隔。如果指定該參數(shù),數(shù)據(jù)只會被導入相應分區(qū)內(nèi)。如果未指定,則默認將數(shù)據(jù)導入至目標表的所有分區(qū)。 |
TEMPORARY PARTITION | 指定數(shù)據(jù)導入的臨時分區(qū)。詳情請參見臨時分區(qū)。 |
label | 導入任務的標識,在數(shù)據(jù)庫內(nèi)唯一。建議您指定Label。
|
column_name | 導入的目標列,必須是目標表中存在的列。該參數(shù)的對應關(guān)系與列名無關(guān),但與其順序一一對應。如果不指定目標列,默認為目標表中的所有列。如果源表中的某個列在目標列不存在,則寫入默認值。如果當前列沒有默認值,導入任務會失敗。如果查詢語句的結(jié)果列類型與目標列的類型不一致,會進行隱式轉(zhuǎn)化,如果不能進行轉(zhuǎn)化,那么INSERT INTO語句會報語法解析錯誤。 |
VALUES | 通過VALUES語句插入一條或者多條數(shù)據(jù)。 重要 VALUES方式僅適用于導入幾條數(shù)據(jù)作為Demo的情況,完全不適用于任何測試和生產(chǎn)環(huán)境。StarRocks系統(tǒng)本身也不適合單條數(shù)據(jù)導入的場景。建議使用INSERT INTO SELECT的方式進行批量導入。 |
expression | 表達式,用以為對應列賦值。 |
DEFAULT | 為對應列賦予默認值。 |
query | 查詢語句,查詢的結(jié)果會導入至目標表中。支持StarRocks提供的所有SQL查詢語法。 |
相關(guān)配置
您可以為INSERT導入任務設定以下配置項。
FE配置項
FE配置項 | 說明 |
insert_load_default_timeout_second | INSERT導入任務的超時時間,單位為秒。如果當前INSERT導入任務在該參數(shù)設定的時間內(nèi)未完成則會被系統(tǒng)取消,狀態(tài)為CANCELLED。目前僅支持通過該參數(shù)為所有INSERT導入任務統(tǒng)一設定超時時間,不支持為單獨的導入任務設置超時時間。默認為3600秒(1小時)。如果導入任務無法在規(guī)定時間內(nèi)完成,您可以通過調(diào)整該參數(shù)延長超時時間。 |
Session變量
Session變量 | 說明 |
enable_insert_strict | INSERT導入是否容忍錯誤數(shù)據(jù)行。
|
query_timeout | SQL命令的超時時間,單位為秒。INSERT語句作為SQL命令,同樣受到該Session變量的限制。您可以通過 |
準備工作
查看權(quán)限
導入操作需要目標表的INSERT權(quán)限。如果您的用戶賬號沒有INSERT權(quán)限,請參考GRANT給用戶賦權(quán),語法為GRANT INSERT ON TABLE <table_name> IN DATABASE <database_name> TO { ROLE <role_name> | USER <user_identity>}
。
建庫建表
在StarRocks中創(chuàng)建數(shù)據(jù)庫load_test
,并在其中創(chuàng)建導入目標表insert_wiki_edit
以及數(shù)據(jù)源表source_wiki_edit
。
本文中演示的操作示例均基于目標表insert_wiki_edit
和數(shù)據(jù)源表source_wiki_edit
。如果您選擇使用自己的表以及數(shù)據(jù),請?zhí)^當前步驟,并根據(jù)使用場景修改需要導入的數(shù)據(jù)。
CREATE DATABASE IF NOT EXISTS load_test;
USE load_test;
CREATE TABLE insert_wiki_edit
(
event_time DATETIME,
channel VARCHAR(32) DEFAULT '',
user VARCHAR(128) DEFAULT '',
is_anonymous TINYINT DEFAULT '0',
is_minor TINYINT DEFAULT '0',
is_new TINYINT DEFAULT '0',
is_robot TINYINT DEFAULT '0',
is_unpatrolled TINYINT DEFAULT '0',
delta INT DEFAULT '0',
added INT DEFAULT '0',
deleted INT DEFAULT '0'
)
DUPLICATE KEY(
event_time,
channel,
user,
is_anonymous,
is_minor,
is_new,
is_robot,
is_unpatrolled
)
PARTITION BY RANGE(event_time)(
PARTITION p06 VALUES LESS THAN ('2015-09-12 06:00:00'),
PARTITION p12 VALUES LESS THAN ('2015-09-12 12:00:00'),
PARTITION p18 VALUES LESS THAN ('2015-09-12 18:00:00'),
PARTITION p24 VALUES LESS THAN ('2015-09-13 00:00:00')
)
DISTRIBUTED BY HASH(user);
CREATE TABLE source_wiki_edit
(
event_time DATETIME,
channel VARCHAR(32) DEFAULT '',
user VARCHAR(128) DEFAULT '',
is_anonymous TINYINT DEFAULT '0',
is_minor TINYINT DEFAULT '0',
is_new TINYINT DEFAULT '0',
is_robot TINYINT DEFAULT '0',
is_unpatrolled TINYINT DEFAULT '0',
delta INT DEFAULT '0',
added INT DEFAULT '0',
deleted INT DEFAULT '0'
)
DUPLICATE KEY(
event_time,
channel,user,
is_anonymous,
is_minor,
is_new,
is_robot,
is_unpatrolled
)
PARTITION BY RANGE(event_time)(
PARTITION p06 VALUES LESS THAN ('2015-09-12 06:00:00'),
PARTITION p12 VALUES LESS THAN ('2015-09-12 12:00:00'),
PARTITION p18 VALUES LESS THAN ('2015-09-12 18:00:00'),
PARTITION p24 VALUES LESS THAN ('2015-09-13 00:00:00')
)
DISTRIBUTED BY HASH(user);
通過INSERT INTO VALUES導入
您可以通過INSERT INTO VALUES語句向指定的表中直接導入數(shù)據(jù)。此導入方式中,多條數(shù)據(jù)用逗號(,)分隔。詳細使用方式,請參見INSERTINSERT。
INSERT INTO VALUES語句導入方式僅適用于導入少量數(shù)據(jù)作為驗證DEMO用途,不適用于大規(guī)模測試或生產(chǎn)環(huán)境。如需大規(guī)模導入數(shù)據(jù),請選擇其他導入方式。
以下示例以insert_load_wikipedia
為Label向數(shù)據(jù)源表source_wiki_edit
中導入兩條數(shù)據(jù)。
INSERT INTO load_test.source_wiki_edit
WITH LABEL insert_load_wikipedia
VALUES
("2015-09-12 00:00:00","#en.wikipedia","AustinFF",0,0,0,0,0,21,5,0),
("2015-09-12 00:00:00","#ca.wikipedia","helloSR",0,1,0,1,0,3,23,0);
參數(shù) | 說明 |
table_name | 導入數(shù)據(jù)的目標表。使用 |
label | 導入任務的標識,在數(shù)據(jù)庫內(nèi)唯一。如果未指定,StarRocks會自動為任務生成一個Label。建議您指定Label。否則,如果當前導入任務因網(wǎng)絡錯誤無法返回結(jié)果,您將無法得知該導入操作是否成功。如果指定了Label,可以通過SQL命令 |
values | 通過VALUES語法插入一條或者多條數(shù)據(jù),多條數(shù)據(jù)用逗號(,)分隔。 |
通過INSERT INTO SELECT導入
您可以通過INSERT INTO SELECT語句將源表中的數(shù)據(jù)進行ETL轉(zhuǎn)換之后,導入到StarRocks內(nèi)表中。源表可以是一張或多張內(nèi)部表或者外部表。目標表必須是StarRocks的內(nèi)表。執(zhí)行該語句之后,系統(tǒng)將SELECT語句結(jié)果導入目標表。
以下示例僅展示導入內(nèi)部表數(shù)據(jù),其操作過程與導入外部表數(shù)據(jù)相同,故不重復演示導入外部表數(shù)據(jù)過程。
以下示例以
insert_load_wikipedia_1
為Label將源表中的數(shù)據(jù)導入至目標表中。INSERT INTO load_test.insert_wiki_edit WITH LABEL insert_load_wikipedia_1 SELECT * FROM load_test.source_wiki_edit;
以下示例以
insert_load_wikipedia_2
為Label將源表中的數(shù)據(jù)導入至目標表的p06
和p12
分區(qū)中。如果不指定目標分區(qū),數(shù)據(jù)將會導入全表;如果指定目標分區(qū),數(shù)據(jù)只會導入指定的分區(qū)。INSERT INTO load_test.insert_wiki_edit PARTITION(p06, p12) WITH LABEL insert_load_wikipedia_2 SELECT * FROM load_test.source_wiki_edit;
如果清空
p06
和p12
分區(qū),則查詢不到先前插入至對應分區(qū)的數(shù)據(jù)。TRUNCATE TABLE load_test.insert_wiki_edit PARTITION(p06, p12); SELECT * FROM load_test.insert_wiki_edit;
以下示例以
insert_load_wikipedia_3
為Label將源表中event_time
和channel
列的數(shù)據(jù)導入至目標表的對應列中。未被導入的列將被賦予默認值。INSERT INTO load_test.insert_wiki_edit WITH LABEL insert_load_wikipedia_3 ( event_time, channel ) SELECT event_time, channel FROM load_test.source_wiki_edit;
通過INSERT OVERWRITE VALUES覆蓋寫入
您可以通過INSERT OVERWRITE VALUES語句向指定的表中覆蓋寫入數(shù)據(jù)。此導入方式中,多條數(shù)據(jù)用逗號(,)分隔。詳細使用方式,請參見INSERTINSERT。
INSERT OVERWRITE VALUES語句導入方式僅適用于導入少量數(shù)據(jù)作為驗證DEMO用途,不適用于大規(guī)模測試或生產(chǎn)環(huán)境。如需大規(guī)模導入數(shù)據(jù),請選擇其他導入方式。
查詢源表,確認其中已有數(shù)據(jù)。
SELECT * FROM load_test.source_wiki_edit;
系統(tǒng)返回如下查詢結(jié)果。
以下示例以insert_load_wikipedia_ow
為Label向源表source_wiki_edit
中覆蓋寫入兩條數(shù)據(jù)。
INSERT OVERWRITE load_test.source_wiki_edit
WITH LABEL insert_load_wikipedia_ow
VALUES
("2015-09-12 00:00:00","#cn.wikipedia","GELongstreet",0,0,0,0,0,36,36,0),
("2015-09-12 00:00:00","#fr.wikipedia","PereBot",0,1,0,1,0,17,17,0);
查詢源表,系統(tǒng)返回如下查詢結(jié)果,表明數(shù)據(jù)已經(jīng)成功覆蓋。
通過INSERT OVERWRITE SELECT覆蓋寫入
您可以通過INSERT OVERWRITE SELECT語句將源表中的數(shù)據(jù)覆蓋寫入至目標表中。INSERT OVERWRITE SELECT將源表中的數(shù)據(jù)進行ETL轉(zhuǎn)換之后,覆蓋寫入到StarRocks內(nèi)表中。源表可以是一張或多張內(nèi)部表或者外部表。目標表必須是StarRocks的內(nèi)表。執(zhí)行該語句之后,系統(tǒng)使用SELECT語句結(jié)果覆蓋目標表的數(shù)據(jù)。詳細使用方式,請參見INSERTINSERT。
以下示例僅展示導入內(nèi)部表數(shù)據(jù),其操作過程與導入外部表數(shù)據(jù)相同,故不重復演示導入外部表數(shù)據(jù)過程。
以下示例以
insert_load_wikipedia_ow_1
為Label將源表中的數(shù)據(jù)覆蓋寫入至目標表中。INSERT OVERWRITE load_test.insert_wiki_edit WITH LABEL insert_load_wikipedia_ow_1 SELECT * FROM load_test.source_wiki_edit;
以下示例以
insert_load_wikipedia_ow_2
為Label將源表中的數(shù)據(jù)覆蓋寫入至目標表的p06
和p12
分區(qū)中。如果不指定目標分區(qū),數(shù)據(jù)將會覆蓋寫入全表;如果指定目標分區(qū),數(shù)據(jù)只會覆蓋寫入指定的分區(qū)。INSERT OVERWRITE load_test.insert_wiki_edit PARTITION(p06, p12) WITH LABEL insert_load_wikipedia_ow_2 SELECT * FROM load_test.source_wiki_edit;
如果清空
p06
和p12
分區(qū),則查詢不到先前插入至對應分區(qū)的數(shù)據(jù)。TRUNCATE TABLE load_test.insert_wiki_edit PARTITION(p06, p12); SELECT * FROM load_test.insert_wiki_edit;
說明對于使用列表達式分區(qū)方式(
PARTITION BY column
)的表,INSERT OVERWRITE支持通過指定分區(qū)鍵的值在目標表上創(chuàng)建不存在的分區(qū)。對于已有的分區(qū),將正常進行覆蓋寫。以下示例創(chuàng)建了分區(qū)表
activity
,向其中導入新數(shù)據(jù)時自動創(chuàng)建了先前不存在的分區(qū):CREATE TABLE load_test.activity ( id INT NOT NULL, dt VARCHAR(10) NOT NULL ) ENGINE=OLAP DUPLICATE KEY(`id`) PARTITION BY (`id`, `dt`) DISTRIBUTED BY HASH(`id`); INSERT OVERWRITE load_test.activity PARTITION(id='4', dt='2022-01-01') WITH LABEL insert_activity_auto_partition VALUES ('4', '2022-01-01');
以下示例以
insert_load_wikipedia_ow_3
為Label將源表中event_time
和channel
列的數(shù)據(jù)覆蓋寫入至目標表的對應列中。未被導入的列將被賦予默認值。INSERT OVERWRITE load_test.insert_wiki_edit WITH LABEL insert_load_wikipedia_ow_3 ( event_time, channel ) SELECT event_time, channel FROM source_wiki_edit;
查看導入任務
您可以通過以下兩種方式來查看導入任務。
方式一:通過EMR StarRocks Manager查看導入任務。詳情請參見查看導入任務詳情。
方式二:通過StarRocks Information Schema庫中的
loads
視圖查看導入任務的進度。該功能自3.1版本起支持。SELECT * FROM information_schema.loads;
有關(guān)
loads
視圖提供的字段詳情,參見loads
。如果您提交了多個導入任務,您可以通過
LABEL
過濾出想要查看的任務。示例如下。SELECT * FROM information_schema.loads WHERE LABEL = 'insert_load_wikipedia_ow';
在返回結(jié)果中,
STATE
顯示導入任務的狀態(tài)。導入任務的狀態(tài)為
CANCELLED
,通過記錄中的ERROR_MSG
字段,可以確定導致任務出錯的原因。導入任務的狀態(tài)為
FINISHED
,表示任務成功。