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 命令需要通过 MySQL 协议提交,创建导入请求会同步返回导入结果。

语法:

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

示例:

INSERT INTO tbl2 WITH LABEL label1 SELECT * FROM tbl3;
INSERT INTO tbl1 VALUES ("qweasdzxcqweasdzxc"), ("a");

注意

当需要使用 CTE(Common Table Expressions) 作为 insert 操作中的查询部分时,必须指定 WITH LABEL 和 column list 部分。示例

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;

下面主要介绍创建导入语句中使用到的参数:

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。

该功能需要 0.11+ 版本。

注意:建议指定 Label 而不是由系统自动分配。如果由系统自动分配,但在 Insert Into 语句执行过程中,因网络错误导致连接断开等,则无法得知 Insert Into 是否成功。而如果指定 Label,则可以再次通过 Label 查看任务结果。

导入结果

Insert Into 本身就是一个 SQL 命令,其返回结果会根据执行结果的不同,分为以下几种:

结果集为空

如果 insert 对应 select 语句的结果集为空,则返回如下:

mysql> insert into tbl1 select * from empty_tbl;
Query OK, 0 rows affected (0.02 sec)
Query OK 表示执行成功。0 rows affected 表示没有数据被导入。

结果集不为空

在结果集不为空的情况下。返回结果分为如下几种情况:

Insert 执行成功并可见:

mysql> insert into tbl1 select * from tbl2;
Query OK, 4 rows affected (0.38 sec)
{'label':'insert_8510c568-9eda-4173-9e36-6adc7d35291c', 'status':'visible', 'txnId':'4005'}mysql> insert into tbl1 with label my_label1 select * from tbl2;
Query OK, 4 rows affected (0.38 sec)
{'label':'my_label1', 'status':'visible', 'txnId':'4005'}mysql> insert into tbl1 select * from tbl2;
Query OK, 2 rows affected, 2 warnings (0.31 sec)
{'label':'insert_f0747f0e-7a35-46e2-affa-13a235f4020d', 'status':'visible', 'txnId':'4005'}mysql> insert into tbl1 select * from tbl2;
Query OK, 2 rows affected, 2 warnings (0.31 sec)
{'label':'insert_f0747f0e-7a35-46e2-affa-13a235f4020d', 'status':'committed', 'txnId':'4005'}

Query OK 表示执行成功。4 rows affected 表示总共有4行数据被导入。2 warnings 表示被过滤的行数。

同时会返回一个 json 串:

{'label':'my_label1', 'status':'visible', 'txnId':'4005'}
{'label':'insert_f0747f0e-7a35-46e2-affa-13a235f4020d', 'status':'committed', 'txnId':'4005'}
{'label':'my_label1', 'status':'visible', 'txnId':'4005', 'err':'some other error'}

label 为用户指定的 label 或自动生成的 label。Label 是该 Insert Into 导入作业的标识。每个导入作业,都有一个在单 database 内部唯一的 Label。

status 表示导入数据是否可见。如果可见,显示 visible,如果不可见,显示 committed。

txnId 为这个 insert 对应的导入事务的 id。

err 字段会显示一些其他非预期错误。

当需要查看被过滤的行时,用户可以通过如下语句

show load where label=“xxx”;
返回结果中的 URL 可以用于查询错误的数据,具体见后面 查看错误行 小结。

数据不可见是一个临时状态,这批数据最终是一定可见的

可以通过如下语句查看这批数据的可见状态:

show transaction where id=4005;
返回结果中的 TransactionStatus 列如果为 visible,则表述数据可见。

Insert 执行失败

执行失败表示没有任何数据被成功导入,并返回如下:

mysql> insert into tbl1 select * from tbl2 where k1 = “a”;
ERROR 1064 (HY000): all partitions have no load data. url: http://10.74.167.16:8042/api/_load_error_log?file=__shard_2/error_log_insert_stmt_ba8bb9e158e4879-ae8de8507c0bf8a2_ba8bb9e158e4879_ae8de8507c0bf8a2
其中 ERROR 1064 (HY000): all partitions have no load data 显示失败原因。后面的 url 可以用于查询错误的数据,具体见后面 查看错误行 小结。

综上,对于 insert 操作返回结果的正确处理逻辑应为:

如果返回结果为 ERROR 1064 (HY000),则表示导入失败。
如果返回结果为 Query OK,则表示执行成功。
如果 rows affected 为 0,表示结果集为空,没有数据被导入。
如果 rows affected 大于 0:
如果 status 为 committed,表示数据还不可见。需要通过 show transaction 语句查看状态直到 visible
如果 status 为 visible,表示数据导入成功。
如果 warnings 大于 0,表示有数据被过滤,可以通过 show load 语句获取 url 查看被过滤的行。
#相关系统配置
#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; 来增加超时时间,单位是秒。

#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; 来增加超时时间,单位是秒。

最佳实践

应用场景

用户希望仅导入几条假数据,验证一下 Doris 系统的功能。此时适合使用 INSERT INTO VALUES 的语法。
用户希望将已经在 Doris 表中的数据进行 ETL 转换并导入到一个新的 Doris 表中,此时适合使用 INSERT INTO SELECT 语法。
用户可以创建一种外部表,如 MySQL 外部表映射一张 MySQL 系统中的表。或者创建 Broker 外部表来映射 HDFS 上的数据文件。然后通过 INSERT INTO SELECT 语法将外部表中的数据导入到 Doris 表中存储。
#数据量
Insert Into 对数据量没有限制,大数据量导入也可以支持。但 Insert Into 有默认的超时时间,用户预估的导入数据量过大,就需要修改系统的 Insert Into 导入超时时间。

导入数据量 = 36G 约≤ 3600s * 10M/s
其中 10M/s 是最大导入限速,用户需要根据当前集群情况计算出平均的导入速度来替换公式中的 10M/s
#完整例子
用户有一张表 store_sales 在数据库 sales 中,用户又创建了一张表叫 bj_store_sales 也在数据库 sales 中,用户希望将 store_sales 中销售记录在 bj 的数据导入到这张新建的表 bj_store_sales 中。导入的数据量约为:10G。

store_sales schema:
(id, total, user_id, sale_timestamp, region)bj_store_sales schema:
(id, total, user_id, sale_timestamp)

集群情况:用户当前集群的平均导入速度约为 5M/s

Step1: 判断是否要修改 Insert Into 的默认超时时间

计算导入的大概时间
10G / 5M/s = 2000s

修改 FE 配置

insert_load_default_timeout_second = 2000

Step2:创建导入任务

由于用户是希望将一张表中的数据做 ETL 并导入到目标表中,所以应该使用 Insert into query_stmt 方式导入。

INSERT INTO bj_store_sales WITH LABEL `label` SELECT id, total, user_id, sale_timestamp FROM store_sales where region = "bj";

常见问题

查看错误行

由于 Insert Into 无法控制错误率,只能通过 enable_insert_strict 设置为完全容忍错误数据或完全忽略错误数据。因此如果 enable_insert_strict 设为 true,则 Insert Into 可能会失败。而如果 enable_insert_strict 设为 false,则可能出现仅导入了部分合格数据的情况。

当返回结果中提供了 url 字段时,可以通过以下命令查看错误行:

SHOW LOAD WARNINGS ON "url";

示例:

SHOW LOAD WARNINGS ON "http://ip:port/api/_load_error_log?file=__shard_13/error_log_insert_stmt_d2cac0a0a16d482d-9041c949a4b71605_d2cac0a0a16d482d_9041c949a4b71605";

错误的原因通常如:源数据列长度超过目的数据列长度、列类型不匹配、分区不匹配、列顺序不匹配等等。

Doris之Insert Into相关推荐

  1. [1.2.0新功能系列:二] Apache Doris 1.2.0 JDBC外表 及 Mutil Catalog

    JDBC 外表 JDBC External Table Of Doris 提供了Doris通过数据库访问的标准接口(JDBC)来访问外部表,外部表省去了繁琐的数据导入工作,也省去了之前ODBC繁杂的驱 ...

  2. Apache Doris ODBC Mysql外表在centos下的使用方法及配置

    直奔主题,下文详解Apache Doris使用ODBC方式实现导入Mysql数据库的详细案例. 1.软件环境 操作系统:CentOS Linux release 7.9 Apache Doris :1 ...

  3. 基于Binlog、FlinkCDC、Doris实现实时数据同步

    基于Binlog.FlinkCDC.Doris实现数据实时同步 Docker部署MySQL docker pull mysql:5.7.32 通过挂载的方式开启一个mysql镜像 docker run ...

  4. 【遇见Doris】Apache Doris在一点资讯自媒体平台的应用

    6月29日,Doris有幸得到中国信通院云大所.大数据技术标准推进委员会的支持,在中国信通院举行了0.11.0新版本预览线下沙龙.各位嘉宾都带来了干货满满的分享.关注Doris官方公众号,后台回复&q ...

  5. Apache Doris技术实践

    文章目录 1 Doris简述 1.1 Doris架构组成介绍 1.1.1 Doris的整体架构 1.1.2 FE 1.1.3 元数据 1.2 Doris特点 1.3 Doris的软硬件需求 1.4 D ...

  6. 最全的Apache Doris教程(收藏版)共9万+字【第一篇】由于是typora编写,有部分图片在本地,识别不出来,请细聊我

    1.Doris 简介 1.1 Doris 概述 Apache Doris 由百度大数据部研发(之前叫百度 Palo,2018 年贡献到 Apache 社区后, 更名为 Doris ),在百度内部,有超 ...

  7. Doris浅略介绍 +部署+使用

    Doris 学习日常记录 (记录学习过程和遇到的坑,仅是个人学习使用) Doris浅略介绍 DORIS 组成 安装Doris步骤 由于IP地址变换,导致的 doris FE 重启失败问题 Doris ...

  8. Doris之导入总览

    导入总览 导入(Load)功能就是将用户的原始数据导入到 Doris 中.导入成功后,用户即可通过 Mysql 客户端查询数据. Doris 支持多种导入方式.建议先完整阅读本文档,再根据所选择的导入 ...

  9. 全国省市县sql(完整版)

     省 Insert into PROVINCE(PROVINCE_ID, NAME, SEQ)Values(4, '山西', 4); Insert into PROVINCE(PROVINCE_I ...

最新文章

  1. Windows Phone SDK update for Windows Phone 7.8
  2. luogu P3410 拍照(最大权闭合图转最小割)
  3. 关于Git的一些经验总结
  4. C++11空指针(nullptr)
  5. 【oracle】日期加减计算
  6. 06-图1 列出连通集 (25 分)
  7. 再议libcurl编程
  8. python多进程优化for循环_Python中for循环中的多进程处理和传递多个参数
  9. Netty工作笔记0056---Unpooled应用实例2
  10. Spring Batch 4.2.0.M1 发布,批处理应用编写框架
  11. 从零开始学习 ASP.NET MVC 1.0 (四) View/Model 全解 【转】
  12. RFID无线射频技术是什么意思
  13. 无人驾驶汽车系统入门(十五)——ROS入门与实践(2)
  14. 在计算机网络中服务器必不可少,2020年全国计算机一级Ms Office试题(总)
  15. HTTP状态码全部说明
  16. 算法之BTree(Java版)
  17. document.getElementById 用法 详解!
  18. mysql命令行进行数据导入和导出
  19. 低通滤波器计算截止评率_技术货:滤波器带宽及对应RC的计算
  20. MLCC电容啸叫如何解决

热门文章

  1. 切换网页窗口时改变页面title标题
  2. python七彩蟒蛇代码_Python实现七彩蟒蛇绘制实例代码
  3. 某项目从3000并发到10W并发的优化记录
  4. php中smarty末班引擎,PHP使用smarty模板引擎
  5. 系统改造升级步骤及注意事项(一)
  6. 计算机软件技术基础 王海燕,认知案例教学法在“计算机软件技术基础”课程中的探讨与应用.doc...
  7. https访问报证书错误_IE打开https网站时,提示此网站的安全证书有问题(证书无效)...
  8. 精美高清壁纸:30款音乐主题壁纸免费下载
  9. 网页打开速度慢的原因 你知道的有几条?
  10. 在 Visual Studio 的解决方案资源管理器中隐藏一些文件