跳到主要内容
版本: 最新版本-3.5

INSERT

将数据插入到指定的表中,或者使用数据覆盖指定的表。 从 v3.2.0 开始,INSERT 支持将数据写入到远程存储中的文件中。 您可以使用 INSERT INTO FILES() 从 StarRocks 卸载数据到远程存储。

您可以使用 SUBMIT TASK 提交异步 INSERT 任务。

语法

  • 数据导入:

    INSERT { INTO | OVERWRITE } [db_name.]<table_name>
    [ PARTITION (<partition_name> [, ...] ) ]
    [ TEMPORARY PARTITION (<temporary_partition_name> [, ...] ) ]
    [ WITH LABEL <label>]
    [ (<column_name>[, ...]) | BY NAME ]
    [ PROPERTIES ("key"="value", ...) ]
    { VALUES ( { <expression> | DEFAULT } [, ...] ) | <query> }
  • 数据卸载:

    INSERT INTO FILES()
    [ WITH LABEL <label> ]
    { VALUES ( { <expression> | DEFAULT } [, ...] ) | <query> }

参数

参数描述
INTO将数据追加到表中。
OVERWRITE使用数据覆盖表。
table_name要加载数据的表的名称。 可以使用表所在的数据库指定,格式为 db_name.table_name
PARTITION要加载数据的分区。 可以指定多个分区,这些分区必须用逗号 (,) 分隔。 必须设置为目标表中存在的分区。 如果指定此参数,则数据将仅插入到指定的分区中。 如果不指定此参数,则数据将插入到所有分区中。
TEMPORARY PARTITION要加载数据的临时分区的名称。 可以指定多个临时分区,这些分区必须用逗号 (,) 分隔。
label数据库中每个数据加载事务的唯一标识标签。 如果未指定,系统会自动为事务生成一个。 我们建议您为事务指定标签。 否则,如果发生连接错误并且没有返回结果,则无法检查事务状态。 您可以通过 SHOW LOAD WHERE label="label" 语句检查事务状态。 有关标签的命名约定,请参阅系统限制
column_name要加载数据的目标列的名称。 它必须设置为目标表中存在的列。 不能同时指定 column_nameBY NAME
  • 如果未指定 BY NAME,则无论目标列名是什么,您指定的目标列都会按顺序与源列一一映射。
  • 如果指定了 BY NAME,则目标列将映射到具有相同名称的源列,而与目标表和源表中的列顺序无关。
  • 如果未指定目标列,则默认值为目标表中的所有列。
  • 如果源表中指定的列在目标列中不存在,则默认值将被写入此列。
  • 如果指定的列没有默认值,则事务将失败。
  • 如果源表的列类型与目标表的列类型不一致,系统将对不匹配的列执行隐式转换。
  • 如果转换失败,将返回语法解析错误。
注意
从 v3.3.1 开始,在主键表上的 INSERT INTO 语句中指定列列表将执行部分更新(而不是早期版本中的完整 Upsert)。 如果未指定列列表,系统将执行完整 Upsert。
BY NAME按名称匹配源列和目标列。 不能同时指定 column_nameBY NAME 如果未指定,则无论目标列名是什么,目标列都会按顺序与源列一一映射。
PROPERTIESINSERT 作业的属性。 每个属性必须是键值对。 有关支持的属性,请参阅PROPERTIES
expression为列分配值的表达式。
DEFAULT为列分配默认值。
query查询语句,其结果将被加载到目标表中。 它可以是 StarRocks 支持的任何 SQL 语句。
FILES()表函数 FILES()。 您可以使用此函数将数据卸载到远程存储。

PROPERTIES

从 v3.4.0 开始,INSERT 语句支持配置 PROPERTIES。

属性描述
timeoutINSERT 作业的超时持续时间。 单位:秒。 您还可以使用变量 insert_timeout 在会话中或全局设置 INSERT 的超时持续时间。
strict_mode使用 FILES() 中的 INSERT 加载数据时是否启用严格模式。 有效值:true(默认)和 false。 启用严格模式后,系统仅加载合格的行。 它会过滤掉不合格的行并返回有关不合格行的详细信息。 有关更多信息,请参阅严格模式。 您还可以使用变量 enable_insert_strict 在会话中或全局为 FILES() 中的 INSERT 启用严格模式。
max_filter_ratioFILES() 中 INSERT 的最大错误容忍度。 它是由于数据质量不足而被过滤掉的数据记录的最大比率。 当不合格数据记录的比率达到此阈值时,作业将失败。 默认值:0。 范围:[0, 1]。 您还可以使用变量 insert_max_filter_ratio 在会话中或全局设置 FILES() 中 INSERT 的最大错误容忍度。
注意
  • strict_modemax_filter_ratio 仅支持 FILES() 中的 INSERT。 来自表的 INSERT 不支持这些属性。
  • 从 v3.4.0 开始,当 enable_insert_strict 设置为 true 时,系统仅加载合格的行。 它会过滤掉不合格的行并返回有关不合格行的详细信息。 相反,在早于 v3.4.0 的版本中,当 enable_insert_strict 设置为 true 时,如果存在不合格的行,INSERT 作业将失败。

返回

Query OK, 5 rows affected, 2 warnings (0.05 sec)
{'label':'insert_load_test', 'status':'VISIBLE', 'txnId':'1008'}
返回描述
受影响的行数指示加载了多少行。 warnings 指示被过滤掉的行。
label数据库中每个数据加载事务的唯一标识标签。 它可以由用户分配,也可以由系统自动分配。
status指示加载的数据是否可见。 VISIBLE:数据已成功加载并且可见。 COMMITTED:数据已成功加载,但目前不可见。
txnId与每个 INSERT 事务对应的 ID 号。

动态覆盖

从 v3.4.0 开始,StarRocks 支持一种新的语义 - 用于分区表的 INSERT OVERWRITE 的动态覆盖。

目前,INSERT OVERWRITE 的默认行为如下

  • 当整体覆盖分区表时(即,不指定 PARTITION 子句),新的数据记录将替换其相应分区中的数据。 如果有未涉及的分区,它们将被截断,而其他分区将被覆盖。
  • 当覆盖空分区表(即,其中没有分区)并指定 PARTITION 子句时,系统将返回错误 ERROR 1064 (HY000): Getting analyzing error. Detail message: Unknown partition 'xxx' in table 'yyy'
  • 当覆盖分区表并在 PARTITION 子句中指定不存在的分区时,系统将返回错误 ERROR 1064 (HY000): Getting analyzing error. Detail message: Unknown partition 'xxx' in table 'yyy'
  • 当使用与 PARTITION 子句中指定的任何分区都不匹配的数据记录覆盖分区表时,系统要么返回错误 ERROR 1064 (HY000): Insert has filtered data in strict mode(如果启用了严格模式),要么过滤掉不合格的数据记录(如果禁用了严格模式)。

新的动态覆盖语义的行为大不相同

当整体覆盖分区表时,新的数据记录将替换其相应分区中的数据。 如果有未涉及的分区,它们将被保留,而不是被截断或删除。 并且如果有新的数据记录对应于不存在的分区,系统将创建该分区。

默认情况下禁用动态覆盖语义。 要启用它,您需要将系统变量 dynamic_overwrite 设置为 true

在当前会话中启用动态覆盖

SET dynamic_overwrite = true;

您也可以在 INSERT OVERWRITE 语句的提示中设置它,以使其仅对该语句生效:。

示例

INSERT /*+set_var(dynamic_overwrite = true)*/ OVERWRITE insert_wiki_edit
SELECT * FROM source_wiki_edit;

使用说明

  • 对于当前版本,当 StarRocks 执行 INSERT INTO 语句时,如果任何数据行与目标表格式不匹配(例如,字符串太长),则默认情况下 INSERT 事务将失败。 您可以将会话变量 enable_insert_strict 设置为 false,以便系统过滤掉与目标表格式不匹配的数据并继续执行事务。

  • 在执行 INSERT OVERWRITE 语句后,StarRocks 会为存储原始数据的分区创建临时分区,将数据插入到临时分区中,并将原始分区与临时分区交换。 所有这些操作都在 Leader FE 节点中执行。 因此,如果在执行 INSERT OVERWRITE 语句时 Leader FE 节点崩溃,则整个加载事务将失败,并且临时分区将被删除。

  • StarRocks 支持通过 INSERT OVERWRITE 语句写入非表达式分区。 但是,当将新数据写入先前不存在的分区时,系统将不会创建不存在的分区。

关于动态覆盖

  • 动态覆盖仅支持表达式分区。 当将新数据写入先前不存在的分区时,系统将自动创建不存在的分区。
  • 动态覆盖支持基于混合表达式的分区。

示例

示例 1:常规用法

以下示例基于表 test,该表包含两列 c1c2c2 列的默认值为 DEFAULT。

  • 将一行数据导入到 test 表中。
INSERT INTO test VALUES (1, 2);
INSERT INTO test (c1, c2) VALUES (1, 2);
INSERT INTO test (c1, c2) VALUES (1, DEFAULT);
INSERT INTO test (c1) VALUES (1);

如果未指定目标列,则默认情况下,列会按顺序加载到目标表中。 因此,在上面的示例中,第一个和第二个 SQL 语句的结果是相同的。

如果目标列(无论是否插入数据)使用 DEFAULT 作为值,则该列将使用默认值作为加载的数据。 因此,在上面的示例中,第三个和第四个语句的输出是相同的。

  • 一次将多行数据加载到 test 表中。
INSERT INTO test VALUES (1, 2), (3, 2 + 2);
INSERT INTO test (c1, c2) VALUES (1, 2), (3, 2 * 2);
INSERT INTO test (c1, c2) VALUES (1, DEFAULT), (3, DEFAULT);
INSERT INTO test (c1) VALUES (1), (3);

因为表达式的结果是等效的,所以第一个和第二个语句的结果是相同的。 第三个和第四个语句的结果是相同的,因为它们都使用默认值。

  • 将查询语句结果导入到 test 表中。
INSERT INTO test SELECT * FROM test2;
INSERT INTO test (c1, c2) SELECT * from test2;
  • 将查询结果导入到 test 表中,并指定分区和标签。
INSERT INTO test PARTITION(p1, p2) WITH LABEL `label1` SELECT * FROM test2;
INSERT INTO test WITH LABEL `label1` (c1, c2) SELECT * from test2;
  • 使用查询结果覆盖 test 表,并指定分区和标签。
INSERT OVERWRITE test PARTITION(p1, p2) WITH LABEL `label1` SELECT * FROM test3;
INSERT OVERWRITE test WITH LABEL `label1` (c1, c2) SELECT * from test3;

示例 2:使用 FILES() 中的 INSERT 从 AWS S3 加载 Parquet 文件

以下示例将 AWS S3 存储桶 inserttest 中的 Parquet 文件 parquet/insert_wiki_edit_append.parquet 中的数据行插入到表 insert_wiki_edit

INSERT INTO insert_wiki_edit
SELECT * FROM FILES(
"path" = "s3://inserttest/parquet/insert_wiki_edit_append.parquet",
"format" = "parquet",
"aws.s3.access_key" = "XXXXXXXXXX",
"aws.s3.secret_key" = "YYYYYYYYYY",
"aws.s3.region" = "ap-southeast-1"
);

示例 3:INSERT 超时

以下示例将源表 source_wiki_edit 中的数据插入到目标表 insert_wiki_edit 中,超时持续时间设置为 2 秒。

INSERT INTO insert_wiki_edit
PROPERTIES(
"timeout" = "2"
)
SELECT * FROM source_wiki_edit;

如果要摄取大型数据集,可以为 timeout 设置更大的值,或者为会话变量 insert_timeout 设置更大的值。

示例 4:INSERT 严格模式和最大过滤比率

以下示例将 AWS S3 存储桶 inserttest 中的 Parquet 文件 parquet/insert_wiki_edit_append.parquet 中的数据行插入到表 insert_wiki_edit 中,启用严格模式以过滤掉不合格的数据记录,并容忍最多 10% 的错误数据

INSERT INTO insert_wiki_edit
PROPERTIES(
"strict_mode" = "true",
"max_filter_ratio" = "0.1"
)
SELECT * FROM FILES(
"path" = "s3://inserttest/parquet/insert_wiki_edit_append.parquet",
"format" = "parquet",
"aws.s3.access_key" = "XXXXXXXXXX",
"aws.s3.secret_key" = "YYYYYYYYYY",
"aws.s3.region" = "us-west-2"
);

示例 5:INSERT 按名称匹配列

以下示例按名称匹配源表和目标表中的每一列

INSERT INTO insert_wiki_edit BY NAME
SELECT event_time, user, channel FROM source_wiki_edit;

在这种情况下,更改 channeluser 的顺序不会更改列映射。