相关文章推荐
很拉风的红酒  ·  使用python ...·  11 月前    · 
安静的回锅肉  ·  h5 监听页面离开-掘金·  1 年前    · 
仗义的楼房  ·  ruby on rails - ...·  1 年前    · 
着急的野马  ·  layui 表单 field ...·  1 年前    · 
暂无图片
暂无图片
暂无图片
暂无图片

Doris系列10-数据导入之Insert into

只是甲 2022-01-09
2417

Table of Contents

一. Insert into 概述

Insert Into 语句的使用方式和 MySQL 等数据库中 Insert Into 语句的使用方式类似。但在 Doris 中,所有的数据写入都是一个独立的导入作业。所以这里将 Insert Into 也作为一种导入方式介绍。

主要的 Insert Into 命令包含以下两种:

  • INSERT INTO tbl SELECT …
  • INSERT INTO tbl (col1, col2, …) VALUES (1, 2, …), (1,3, …);
  • 其中第二种命令仅用于 Demo,不要使用在测试或生产环境中。

    INSERT INTO table_name [partition_info] [WITH LABEL label] [col_list] [query_stmt] [VALUES];

    partition_info
    导入表的目标分区,如果指定目标分区,则只会导入符合目标分区的数据。如果没有指定,则默认值为这张表的所有分区。

    col_list
    导入表的目标列,可以以任意的顺序存在。如果没有指定目标列,那么默认值是这张表的所有列。如果待表中的某个列没有存在目标列中,那么这个列需要有默认值,否则 Insert Into 就会执行失败。
    如果查询语句的结果列类型与目标列的类型不一致,那么会调用隐式类型转化,如果不能够进行转化,那么 Insert Into 语句会报语法解析错误。

    query_stmt
    通过一个查询语句,将查询语句的结果导入到 Doris 系统中的其他表。查询语句支持任意 Doris 支持的 SQL 查询语法。

    VALUES
    用户可以通过 VALUES 语法插入一条或者多条数据。
    注意:VALUES 方式仅适用于导入几条数据作为导入 DEMO 的情况,完全不适用于任何测试和生产环境。Doris 系统本身也不适合单条数据导入的场景。建议使用 INSERT INTO SELECT 的方式进行批量导入。

    WITH LABEL
    INSERT 操作作为一个导入任务,也可以指定一个 label。如果不指定,则系统会自动指定一个 UUID 作为 label。

    insert into 支持with语句

    INSERT INTO tbl1 WITH LABEL label1 WITH cte1 AS (SELECT * FROM tbl1), cte2 AS (SELECT * FROM tbl2) SELECT k1 FROM cte1 JOIN cte2 WHERE cte1.k1 = 1; INSERT INTO tbl1 (k1) WITH cte1 AS (SELECT * FROM tbl1), cte2 AS (SELECT * FROM tbl2) SELECT k1 FROM cte1 JOIN cte2 WHERE cte1.k1 = 1;

    二. 相关系统配置

    2.1 FE 配置

    timeout
    导入任务的超时时间(以秒为单位),导入任务在设定的 timeout 时间内未完成则会被系统取消,变成 CANCELLED。

    目前 Insert Into 并不支持自定义导入的 timeout 时间,所有 Insert Into 导入的超时时间是统一的,默认的 timeout 时间为1小时。如果导入的源文件无法再规定时间内完成导入,则需要调整 FE 的参数insert_load_default_timeout_second。

    同时 Insert Into 语句收到 Session 变量 query_timeout 的限制。可以通过 SET query_timeout = xxx; 来增加超时时间,单位是秒。

    2.2 Session 变量

    enable_insert_strict:
    Insert Into 导入本身不能控制导入可容忍的错误率。用户只能通过 enable_insert_strict 这个 Session 参数用来控制。

    当该参数设置为 false 时,表示至少有一条数据被正确导入,则返回成功。如果有失败数据,则还会返回一个 Label。

    当该参数设置为 true 时,表示如果有一条数据错误,则导入失败。

    默认为 false。可通过 SET enable_insert_strict = true; 来设置。

    query_timeout
    Insert Into 本身也是一个 SQL 命令,因此 Insert Into 语句也受到 Session 变量 query_timeout 的限制。可以通过 SET query_timeout = xxx; 来增加超时时间,单位是秒。

    三. Insert 实例

    理论上数据量没有限制,但是要修改session的 query_timeout参数,具体可以参考10M/S 这个速度来设置。

    mysql> create table ods_fact_sale like table3; Query OK, 0 rows affected (0.02 sec) mysql> show create table ods_fact_sale\G *************************** 1. row *************************** Table: ods_fact_sale Create Table: CREATE TABLE `ods_fact_sale` ( `id` bigint(20) NULL COMMENT "", `sale_date` varchar(100) NULL COMMENT "", `prod_name` varchar(32) NULL COMMENT "", `sale_nums` bigint(20) SUM NULL DEFAULT "0" COMMENT "" ) ENGINE=OLAP AGGREGATE KEY(`id`, `sale_date`, `prod_name`) COMMENT "OLAP" DISTRIBUTED BY HASH(`id`) BUCKETS 10 PROPERTIES ( "replication_allocation" = "tag.location.default: 1", "in_memory" = "false", "storage_format" = "V2" 1 row in set (0.00 sec) mysql> mysql> select count(*) from table3; +-----------+ | count(*) | +-----------+ | 767830000 | +-----------+ 1 row in set (18.87 sec) mysql> mysql> show variables like 'query_timeout'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | query_timeout | 300 | +---------------+-------+ 1 row in set (0.01 sec) mysql> mysql> insert into ods_fact_sale select * from table3; ERROR 1105 (HY000): errCode = 2, detailMessage = Execute timeout mysql> mysql> mysql> mysql> set query_timeout = 3000; Query OK, 0 rows affected (0.00 sec) mysql> insert into ods_fact_sale select * from table3; Query OK, 767830000 rows affected (18 min 31.45 sec) {'label':'insert_d3f9a8d958c6498c-8767ad465c5d292b', 'status':'VISIBLE', 'txnId':'2119'}