首批通过分布式安全可靠测评,为关键业务系统打造
全量旁路导入
更新时间:2025-10-13 15:32:00
本文介绍如何通过 LOAD DATA 语句、INSERT INTO SELECT 语句和 CREATE TABLE AS SELECT 语句实现全量旁路导入。
注意事项
在使用全量旁路导入时,有以下注意事项:
OceanBase 数据库从 V4.3.0 版本开始支持 LOB 数据类型的旁路导入。
旁路导入期间会加表锁,表无法被写入其他数据,整个过程中表是只读的。
全量旁路导入适用于大表首次导入、10 GB~TB 级别的数据迁移以及 CPU 和内存都不是特别充裕的场景,因为旁路导入的执行路径短,可以省 CPU 开销。
LOAD DATA语句支持在多行事务中运行,在执行时会主动提交之前的事务。使用
INSERT INTO SELECT语句旁路导入数据时,只支持 PDML(Parallel Data Manipulation Language,并行数据操纵语言),非 PDML 不能用旁路导入。
使用 LOAD DATA 语句旁路导入数据
LOAD DATA 语句通过使用 append/direct() Hint 来执行旁路导入,在未指定 Hint 时能基于配置项 default_load_mode 确定导入数据的行为。
注意
OceanBase 数据库通过并行处理技术优化 LOAD DATA 的数据导入速率。该操作将数据分成多个子任务并行执行,每个子任务都视为独立的事务,执行顺序是不固定的。因此对于没有主键的表,数据写入顺序可能与原文件中的顺序不同。
使用限制
- 在导入过程中无法同时执行两个写操作语句(即不能同时写一个表),因为导入过程中会先加表锁,并且整个导入过程中只能进行读操作。
- 不支持在触发器(Trigger)使用。
- 不支持含有生成列的表(某些索引会产生隐藏生成列,例如 KEY
idx_c2(c2(16)) GLOBAL)。 - 不支持单行超过 2M 的数据导入。
- 不支持 Liboblog 和闪回查询(Flashback Query)。
使用语法
LOAD DATA /*+ [APPEND | DIRECT(need_sort,max_error,'full')] parallel(N) */ [REMOTE_OSS | LOCAL] INFILE 'file_name' INTO TABLE table_name [COMPRESSION]...
更多 LOAD DATA 语法的信息,请参见 LOAD DATA。
参数解释:
| 参数 | 描述 |
|---|---|
| APPEND | DIRECT() | 使用 Hint 启用旁路导入功能。
|
| parallel(N) | 加载数据的并行度,必填项,默认为 4。 |
| REMOTE_OSS | LOCAL | 可选项,
|
| file_name | 指定输入文件的路径和文件名。 file_name 有以下格式:
说明在导入 OSS 上的文件时,需要确保以下信息:
|
| table_name | 导入数据的表的名称,支持指定表任意列数目。 |
| COMPRESSION | 指定压缩文件格式,取值有
|
使用示例
说明
下面的示例是从服务器端文件导入数据的方法。OceanBase 数据库 LOAD DATA 语句旁路导入数据还支持加载本地文件(LOCAL INFILE)的方式。更多有关 LOAD DATA LOCAL INFILE 的示例信息,请参见 使用 LOAD DATA 语句导入数据
登录到需要连接 OBServer 节点所在的机器上,在
/home/admin目录下创建测试数据。说明
OceanBase 数据库中的
LOAD DATA语句仅支持加载 OBServer 节点本地的输入文件。因此,需要在导入之前将文件拷贝到某台 OBServer 上。进入 OBServer 节点所在的机器。
[xxx@xxx /home/admin]# ssh admin@10.10.10.1创建测试数据
tbl1.csv。[admin@xxx /home/admin]# vi tbl1.csv 1,11 2,22 3,33
设置导入的文件路径。
设置系统变量
secure_file_priv,配置导入或导出文件时可以访问的路径。注意
由于安全原因,设置系统变量
secure_file_priv时,只能通过本地 Socket 连接数据库执行修改该全局变量的 SQL 语句。更多信息,请参见 secure_file_priv。登录到需要连接 OBServer 节点所在的机器上。
[xxx@xxx /home/admin]# ssh admin@10.10.10.1执行以下命令,通过本地 Unix Socket 连接方式连接租户
mysql001。obclient -S /home/admin/oceanbase/run/sql.sock -uroot@mysql001 -p******设置导入路径为
/home/admin。obclient [(none)]> SET GLOBAL secure_file_priv = "/home/admin"; Query OK, 0 rows affected
重新连接数据库后,使用
LOAD /*+ DIRECT */ DATA语句导入数据。创建表
tbl2。obclient [test]> CREATE TABLE tbl2(col1 INT PRIMARY KEY,col2 INT); Query OK, 0 rows affected查询表
tbl2是否有数据,此时显示表为空。obclient [test]> SELECT * FROM tbl2; Empty set使用旁路导入将
tbl1.csv文件中的数据导入到表tbl2。指定表
tbl2的所有列导入数据。obclient [test]> LOAD DATA /*+ direct(true,1024,'full') parallel(16) */ INFILE '/home/admin/tbl1.csv' INTO TABLE tbl2 FIELDS TERMINATED BY ','; Query OK, 3 rows affected Records: 3 Deleted: 0 Skipped: 0 Warnings: 0指定表
tbl2的指定任意列导入数据。例如指定col1,col2列。obclient [test]> LOAD DATA /*+ direct(true,1024,'full') parallel(16) */ INFILE '/home/admin/tbl1.csv' INTO TABLE tbl2 FIELDS TERMINATED BY ','(col1,col2); Query OK, 3 rows affected Records: 3 Deleted: 0 Skipped: 0 Warnings: 0使用配置项
default_load_mode导入数据。设置
default_load_mode的值为FULL_DIRECT_WRITE。obclient [test]> ALTER SYSTEM SET default_load_mode ='FULL_DIRECT_WRITE';不指定
LOAD DATA语句的 Hint。obclient [test]> LOAD DATA INFILE '/home/admin/tbl1.csv' INTO TABLE tbl2 FIELDS TERMINATED BY ',';
验证表
tbl2中是否已导入数据。obclient [test]> SELECT * FROM tbl2;查询结果如下:
+------+------+ | col1 | col2 | +------+------+ | 1 | 11 | | 2 | 22 | | 3 | 33 | +------+------+ 3 rows in set结果显示表
tbl2中已导入数据。
登录到需要连接 OBServer 节点所在的机器上,在
/home/admin目录下创建测试数据tbl1。说明
OceanBase 数据库中的
LOAD DATA语句仅支持加载 OBServer 节点本地的输入文件。因此,需要在导入之前将文件拷贝到某台 OBServer 上。进入 OBServer 节点所在的机器。
[xxx@xxx /home/admin]# ssh admin@10.10.10.1创建测试数据
tbl1.csv。[admin@xxx /home/admin]# vi tbl1.csv 1,11 2,22 3,33
设置导入的文件路径。
设置系统变量
secure_file_priv,配置导入或导出文件时可以访问的路径。注意
由于安全原因,设置系统变量
secure_file_priv时,只能通过本地 Socket 连接数据库执行修改该全局变量的 SQL 语句。更多信息,请参见 secure_file_priv。登录到需要连接 OBServer 节点所在的机器上。
[xxx@xxx /home/admin]# ssh admin@10.10.10.1执行以下命令,通过本地 Unix Socket 连接方式连接租户
oracle001。obclient -S /home/admin/oceanbase/run/sql.sock -usys@oracle001 -p******设置导入路径为
/home/admin。obclient [(none)]> SET GLOBAL secure_file_priv = "/home/admin"; Query OK, 0 rows affected
重新连接数据库后,使用
LOAD /*+ DIRECT */ DATA语句导入数据。创建表
tbl2。obclient [SYS]> CREATE TABLE tbl2(col1 INT PRIMARY KEY,col2 INT); Query OK, 0 rows affected查询表
tbl2是否有数据,此时显示表为空。obclient [SYS]> SELECT * FROM tbl2; Empty set使用旁路导入将
tbl1.csv文件中的数据导入到表tbl2。指定表
tbl2的所有列导入数据。obclient [SYS]> LOAD DATA /*+ direct(true,1024,'full') parallel(16) */ INFILE '/home/admin/tbl1.csv' INTO TABLE tbl2 FIELDS TERMINATED BY ','; Query OK, 3 rows affected Records: 3 Deleted: 0 Skipped: 0 Warnings: 0指定表
tbl2的指定任意列导入数据。例如指定col1,col2列。obclient [SYS]> LOAD DATA /*+ direct(true,1024,'full') parallel(16) */ INFILE '/home/admin/tbl1.csv' INTO TABLE tbl2 FIELDS TERMINATED BY ','(col1,col2); Query OK, 3 rows affected Records: 3 Deleted: 0 Skipped: 0 Warnings: 0使用配置项
default_load_mode导入数据。设置
default_load_mode的值为FULL_DIRECT_WRITE。obclient [SYS]> ALTER SYSTEM SET default_load_mode ='FULL_DIRECT_WRITE';不指定
LOAD DATA语句的 Hint。obclient [SYS]> LOAD DATA INFILE '/home/admin/tbl1.csv' INTO TABLE tbl2 FIELDS TERMINATED BY ',';
验证表
tbl2中是否已导入数据。obclient [SYS]> SELECT * FROM tbl2;查询结果如下:
+------+------+ | col1 | col2 | +------+------+ | 1 | 11 | | 2 | 22 | | 3 | 33 | +------+------+ 3 rows in set结果显示表
tbl2中已导入数据。
使用 INSERT INTO SELECT 语句旁路导入数据
INSERT INTO SELECT 语句通过 Hint 使用 append/direct() 加上 enable_parallel_dml 来执行旁路导入,在未指定 Hint 时能基于配置项 default_load_mode 确定导入数据的行为。
使用限制
- 只支持 PDML(Parallel Data Manipulation Language,并行数据操纵语言),非 PDML 不能用旁路导入。有关并行 DML 的更多信息,参见 并行 DML。
- 在导入过程中无法同时执行两个写操作语句(即不能同时写一个表),因为导入过程中会先加表锁,并且整个导入过程中只能进行读操作。
- 旁路导入属于 DDL 语句,无法在多行事务(包含多个操作的事务)中执行。
- 不能在 Begin 中执行。
- Autocommit 必须设置为 1。
- 不支持在触发器(Trigger)使用。
- 不支持含有生成列的表(某些索引会产生隐藏生成列,例如 KEY
idx_c2(c2(16)) GLOBAL)。 - 不支持 Liboblog 和闪回查询(Flashback Query)。
使用语法
INSERT /*+ [APPEND |DIRECT(need_sort,max_error,'full')] enable_parallel_dml parallel(N) */ INTO table_name select_sentence
更多 INSERT INTO 语法的信息,请参见 INSERT(MySQL 模式) 和 INSERT(Oracle 模式)。
参数解释:
| 参数 | 描述 |
|---|---|
| APPEND | DIRECT() | 使用 Hint 启用旁路导入功能。
|
| enable_parallel_dml | 加载数据的并行度。
说明一般情况下, |
| parallel(N) | 加载数据的并行度,必填项,取值是大于 1 的整数。 |
使用示例
使用旁路导入将表 tbl2 中的部分数据导入到 tbl1 中。
查询表
tbl1是否有数据,此时显示表为空。obclient [test]> SELECT * FROM tbl1; Empty set查询表
tbl2是否有数据。obclient [test]> SELECT * FROM tbl2;查询到表
tbl2有数据。+------+------+------+ | col1 | col2 | col3 | +------+------+------+ | 1 | a1 | 11 | | 2 | a2 | 22 | | 3 | a3 | 33 | +------+------+------+ 3 rows in set使用旁路导入将表
tbl2中的数据导入到表tbl1。指定
INSERT INTO SELECT语句的 Hint。obclient [test]> INSERT /*+ DIRECT(true, 0, 'full') enable_parallel_dml parallel(16) */ INTO tbl1 SELECT t2.col1,t2.col3 FROM tbl2 t2; Query OK, 3 rows affected Records: 3 Duplicates: 0 Warnings: 0不指定
INSERT INTO SELECT语句的 Hint。设置配置项
default_load_mode的值为FULL_DIRECT_WRITE。obclient [test]> ALTER SYSTEM SET default_load_mode ='FULL_DIRECT_WRITE';obclient [test]> INSERT INTO tbl1 SELECT t2.col1,t2.col3 FROM tbl1 t2;
验证表
tbl1中是否已导入数据。obclient [test]> SELECT * FROM tbl1;查询结果如下:
+------+------+ | col1 | col2 | +------+------+ | 1 | 11 | | 2 | 22 | | 3 | 33 | +------+------+ 3 rows in set结果显示表
tbl1中已导入数据。(可选)在
EXPLAIN EXTENDED语句的返回结果的Note中,查看是否通过旁路导入写入的数据。obclient [test]> EXPLAIN EXTENDED INSERT /*+ direct(true, 0, 'full') enable_parallel_dml parallel(16) */ INTO tbl1 SELECT t2.col1,t2.col3 FROM tbl2 t2;返回结果如下:
+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Query Plan | +--------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ============================================================================== | | |ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| | | ------------------------------------------------------------------------------ | | |0 |PX COORDINATOR | |3 |27 | | | |1 |└─EXCHANGE OUT DISTR |:EX10001 |3 |27 | | | |2 | └─INSERT | |3 |26 | | | |3 | └─EXCHANGE IN DISTR | |3 |1 | | | |4 | └─EXCHANGE OUT DISTR (RANDOM)|:EX10000 |3 |1 | | | |5 | └─SUBPLAN SCAN |ANONYMOUS_VIEW1|3 |1 | | | |6 | └─PX BLOCK ITERATOR | |3 |1 | | | |7 | └─TABLE FULL SCAN |t2 |3 |1 | | | ============================================================================== | | Outputs & filters: | | ------------------------------------- | | 0 - output(nil), filter(nil), rowset=16 | | 1 - output(nil), filter(nil), rowset=16 | | dop=16 | | 2 - output(nil), filter(nil) | | columns([{tbl1: ({tbl1: (tbl1.__pk_increment(0x7efa63627790), tbl1.col1(0x7efa63611980), tbl1.col3(0x7efa63611dc0))})}]), partitions(p0), | | column_values([T_HIDDEN_PK(0x7efa63627bd0)], [column_conv(INT,PS:(11,0),NULL,ANONYMOUS_VIEW1.col1(0x7efa63626f10))(0x7efa63627ff0)], [column_conv(INT, | | PS:(11,0),NULL,ANONYMOUS_VIEW1.col3(0x7efa63627350))(0x7efa6362ff20)]) | | 3 - output([T_HIDDEN_PK(0x7efa63627bd0)], [ANONYMOUS_VIEW1.col1(0x7efa63626f10)], [ANONYMOUS_VIEW1.col3(0x7efa63627350)]), filter(nil), rowset=16 | | 4 - output([T_HIDDEN_PK(0x7efa63627bd0)], [ANONYMOUS_VIEW1.col1(0x7efa63626f10)], [ANONYMOUS_VIEW1.col3(0x7efa63627350)]), filter(nil), rowset=16 | | dop=16 | | 5 - output([ANONYMOUS_VIEW1.col1(0x7efa63626f10)], [ANONYMOUS_VIEW1.col3(0x7efa63627350)]), filter(nil), rowset=16 | | access([ANONYMOUS_VIEW1.col1(0x7efa63626f10)], [ANONYMOUS_VIEW1.col3(0x7efa63627350)]) | | 6 - output([t2.col1(0x7efa63625ed0)], [t2.col3(0x7efa63626780)]), filter(nil), rowset=16 | | 7 - output([t2.col1(0x7efa63625ed0)], [t2.col3(0x7efa63626780)]), filter(nil), rowset=16 | | access([t2.col1(0x7efa63625ed0)], [t2.col3(0x7efa63626780)]), partitions(p0) | | is_index_back=false, is_global_index=false, | | range_key([t2.__pk_increment(0x7efa63656410)]), range(MIN ; MAX)always true | | Used Hint: | | ------------------------------------- | | /*+ | | | | USE_PLAN_CACHE( NONE ) | | PARALLEL(16) | | ENABLE_PARALLEL_DML | | DIRECT(TRUE, 0, 'FULL') | | */ | | Qb name trace: | | ------------------------------------- | | stmt_id:0, stmt_type:T_EXPLAIN | | stmt_id:1, INS$1 | | stmt_id:2, SEL$1 | | Outline Data: | | ------------------------------------- | | /*+ | | BEGIN_OUTLINE_DATA | | PARALLEL(@"SEL$1" "t2"@"SEL$1" 16) | | FULL(@"SEL$1" "t2"@"SEL$1") | | USE_PLAN_CACHE( NONE ) | | PARALLEL(16) | | ENABLE_PARALLEL_DML | | OPTIMIZER_FEATURES_ENABLE('4.3.3.0') | | DIRECT(TRUE, 0, 'FULL') | | END_OUTLINE_DATA | | */ | | Optimization Info: | | ------------------------------------- | | t2: | | table_rows:3 | | physical_range_rows:3 | | logical_range_rows:3 | | index_back_rows:0 | | output_rows:3 | | table_dop:16 | | dop_method:Global DOP | | avaiable_index_name:[tbl2] | | stats info:[version=0, is_locked=0, is_expired=0] | | dynamic sampling level:0 | | estimation method:[DEFAULT, STORAGE] | | Plan Type: | | DISTRIBUTED | | Note: | | Degree of Parallelism is 16 because of hint | | Direct-mode is enabled in insert into select | +--------------------------------------------------------------------------------------------------------------------------------------------------------------+ 77 rows in set (0.009 sec)
使用旁路导入将表 tbl4 中的部分数据导入到 tbl3 中。
查询表
tbl3是否有数据,此时显示表为空。obclient [test]> SELECT * FROM tbl3; Empty set查询表
tbl4是否有数据。obclient [test]> SELECT * FROM tbl4;查询到表
tbl4有数据。+------+------+------+ | COL1 | COL2 | COL3 | +------+------+------+ | 1 | a1 | 11 | | 2 | a2 | 22 | | 3 | a3 | 33 | +------+------+------+ 3 rows in set (0.000 sec)使用旁路导入将表
tbl4中的数据导入到表tbl3。指定
INSERT INTO SELECT语句的 Hint。obclient [test]> INSERT /*+ direct(true, 0, 'full') enable_parallel_dml parallel(16) */ INTO tbl3 SELECT t2.col1, t2.col3 FROM tbl4 t2 WHERE ROWNUM <= 10000; Query OK, 3 rows affected Records: 3 Duplicates: 0 Warnings: 0不指定
INSERT INTO SELECT语句的 Hint。设置配置项
default_load_mode的值为FULL_DIRECT_WRITE。obclient [test]> ALTER SYSTEM SET default_load_mode ='FULL_DIRECT_WRITE';obclient [test]> INSERT INTO tbl3 SELECT t2.col1, t2.col3 FROM tbl4 t2 WHERE ROWNUM <= 10000;
验证表
tbl3中是否已导入数据。obclient [test]> SELECT * FROM tbl3;查询结果如下:
+------+------+ | col1 | col3 | +------+------+ | 1 | 11 | | 2 | 22 | | 3 | 33 | +------+------+ 3 rows in set结果显示表
tbl3中已导入数据。(可选)在
EXPLAIN EXTENDED语句的返回结果的Note中,查看是否通过旁路导入写入的数据。obclient [test]> EXPLAIN EXTENDED INSERT /*+ direct(true, 0, 'full') enable_parallel_dml parallel(16) */ INTO tbl3 SELECT t2.col1,t2.col3 FROM tbl4 t2;返回结果如下:
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Query Plan | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | =================================================================================== | | |ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| | | ----------------------------------------------------------------------------------- | | |0 |OPTIMIZER STATS MERGE | |3 |29 | | | |1 |└─PX COORDINATOR | |3 |29 | | | |2 | └─EXCHANGE OUT DISTR |:EX10001 |3 |27 | | | |3 | └─INSERT | |3 |27 | | | |4 | └─OPTIMIZER STATS GATHER | |3 |1 | | | |5 | └─EXCHANGE IN DISTR | |3 |1 | | | |6 | └─EXCHANGE OUT DISTR (RANDOM) |:EX10000 |3 |1 | | | |7 | └─SUBPLAN SCAN |ANONYMOUS_VIEW1|3 |1 | | | |8 | └─PX BLOCK ITERATOR | |3 |1 | | | |9 | └─COLUMN TABLE FULL SCAN|T2 |3 |1 | | | =================================================================================== | | Outputs & filters: | | ------------------------------------- | | 0 - output(nil), filter(nil), rowset=16 | | 1 - output([column_conv(NUMBER,PS:(-1,0),NULL,ANONYMOUS_VIEW1.COL1(0x7ef8f6027720))(0x7ef8f60287f0)], [column_conv(NUMBER,PS:(-1,0),NULL,ANONYMOUS_VIEW1.COL3(0x7ef8f6027b60))(0x7ef8f6030710)]), filter(nil), rowset=16 | | 2 - output([column_conv(NUMBER,PS:(-1,0),NULL,ANONYMOUS_VIEW1.COL1(0x7ef8f6027720))(0x7ef8f60287f0)], [column_conv(NUMBER,PS:(-1,0),NULL,ANONYMOUS_VIEW1.COL3(0x7ef8f6027b60))(0x7ef8f6030710)]), filter(nil), rowset=16 | | dop=16 | | 3 - output([column_conv(NUMBER,PS:(-1,0),NULL,ANONYMOUS_VIEW1.COL1(0x7ef8f6027720))(0x7ef8f60287f0)], [column_conv(NUMBER,PS:(-1,0),NULL,ANONYMOUS_VIEW1.COL3(0x7ef8f6027b60))(0x7ef8f6030710)]), filter(nil) | | columns([{TBL3: ({TBL3: (TBL3.__pk_increment(0x7ef8f6027fa0), TBL3.COL1(0x7ef8f6011d50), TBL3.COL3(0x7ef8f6012190))})}]), partitions(p0), | | column_values([T_HIDDEN_PK(0x7ef8f60283e0)], [column_conv(NUMBER,PS:(-1,0),NULL,ANONYMOUS_VIEW1.COL1(0x7ef8f6027720))(0x7ef8f60287f0)], [column_conv(NUMBER, | | PS:(-1,0),NULL,ANONYMOUS_VIEW1.COL3(0x7ef8f6027b60))(0x7ef8f6030710)]) | | 4 - output([column_conv(NUMBER,PS:(-1,0),NULL,ANONYMOUS_VIEW1.COL1(0x7ef8f6027720))(0x7ef8f60287f0)], [column_conv(NUMBER,PS:(-1,0),NULL,ANONYMOUS_VIEW1.COL3(0x7ef8f6027b60))(0x7ef8f6030710)], | | [T_HIDDEN_PK(0x7ef8f60283e0)]), filter(nil), rowset=16 | | 5 - output([T_HIDDEN_PK(0x7ef8f60283e0)], [ANONYMOUS_VIEW1.COL1(0x7ef8f6027720)], [ANONYMOUS_VIEW1.COL3(0x7ef8f6027b60)]), filter(nil), rowset=16 | | 6 - output([T_HIDDEN_PK(0x7ef8f60283e0)], [ANONYMOUS_VIEW1.COL1(0x7ef8f6027720)], [ANONYMOUS_VIEW1.COL3(0x7ef8f6027b60)]), filter(nil), rowset=16 | | dop=16 | | 7 - output([ANONYMOUS_VIEW1.COL1(0x7ef8f6027720)], [ANONYMOUS_VIEW1.COL3(0x7ef8f6027b60)]), filter(nil), rowset=16 | | access([ANONYMOUS_VIEW1.COL1(0x7ef8f6027720)], [ANONYMOUS_VIEW1.COL3(0x7ef8f6027b60)]) | | 8 - output([T2.COL1(0x7ef8f60264c0)], [T2.COL3(0x7ef8f6026f90)]), filter(nil), rowset=16 | | 9 - output([T2.COL1(0x7ef8f60264c0)], [T2.COL3(0x7ef8f6026f90)]), filter(nil), rowset=16 | | access([T2.COL1(0x7ef8f60264c0)], [T2.COL3(0x7ef8f6026f90)]), partitions(p0) | | is_index_back=false, is_global_index=false, | | range_key([T2.__pk_increment(0x7ef8f60584a0)]), range(MIN ; MAX)always true | | Used Hint: | | ------------------------------------- | | /*+ | | | | USE_PLAN_CACHE( NONE ) | | PARALLEL(16) | | ENABLE_PARALLEL_DML | | DIRECT(TRUE, 0, 'FULL') | | */ | | Qb name trace: | | ------------------------------------- | | stmt_id:0, stmt_type:T_EXPLAIN | | stmt_id:1, INS$1 | | stmt_id:2, SEL$1 | | Outline Data: | | ------------------------------------- | | /*+ | | BEGIN_OUTLINE_DATA | | PARALLEL(@"SEL$1" "T2"@"SEL$1" 16) | | FULL(@"SEL$1" "T2"@"SEL$1") | | USE_COLUMN_TABLE(@"SEL$1" "T2"@"SEL$1") | | USE_PLAN_CACHE( NONE ) | | PARALLEL(16) | | ENABLE_PARALLEL_DML | | OPTIMIZER_FEATURES_ENABLE('4.3.3.0') | | DIRECT(TRUE, 0, 'FULL') | | END_OUTLINE_DATA | | */ | | Optimization Info: | | ------------------------------------- | | T2: | | table_rows:3 | | physical_range_rows:3 | | logical_range_rows:3 | | index_back_rows:0 | | output_rows:3 | | table_dop:16 | | dop_method:Global DOP | | avaiable_index_name:[TBL4] | | stats info:[version=0, is_locked=0, is_expired=0] | | dynamic sampling level:0 | | estimation method:[DEFAULT, STORAGE] | | Plan Type: | | DISTRIBUTED | | Note: | | Degree of Parallelism is 16 because of hint | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 82 rows in set (0.006 sec)
使用 CREATE TABLE AS SELECT 语句旁路导入数据
CREATE TABLE AS SELECT 语句通过设置 DIRECT() Hint 来指定旁路导入的导数方式,在未指定 Hint 时能基于配置项 default_load_mode 确定导入数据的行为。
使用语法
CREATE /*+ [APPEND | DIRECT(need_sort,max_error,load_type)] parallel(N) */ TABLE table_name [AS] select_sentence
更多 CREATE TABLE 语法的信息,请参见 CREATE TABLE(MySQL 模式) 和 CREATE TABLE(Oracle 模式)。
参数解释:
| 参数 | 描述 |
|---|---|
| APPEND | DIRECT() | 使用 Hint 启用旁路导入功能。
|
| parallel(N) | 加载数据的并行度,必填项,取值是大于 1 的整数。 |
使用示例
使用旁路导入将表 tbl1 中的数据导入到其他表中。
创建表
tbl1。obclient [test]> CREATE TABLE tbl1(c1 int);插入数据到表
tbl1。obclient [test]> INSERT INTO tbl1 VALUES (1),(2),(3);查询表
tbl1中的数据。obclient [test]> SELECT * FROM tbl1;查询结果如下:
+------+ | c1 | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (0.027 sec)使用旁路导入将表
tbl1中数据导入到表tbl2。指定
CREATE TABLE AS SELECT语句的 Hint。使用
APPENDHint 旁路导入数据。obclient [test]> CREATE /*+ append parallel(4) */ TABLE tbl2 AS SELECT * FROM tbl1;使用
DIRECTHint 旁路导入数据。obclient [test]> CREATE /*+ direct(true, 0, 'full') parallel(4) */ TABLE tbl2 AS SELECT * FROM tbl1;
不指定
CREATE TABLE AS SELECT语句的 Hint。设置配置项
default_load_mode的值为FULL_DIRECT_WRITE。obclient [test]> ALTER SYSTEM SET default_load_mode ='FULL_DIRECT_WRITE';obclient [test]> CREATE TABLE tbl2 AS SELECT * FROM tbl1;
验证表
tbl2中是否已导入数据。obclient [test]> SELECT * FROM tbl2;查询结果如下:
+------+ | c1 | +------+ | 1 | | 3 | | 2 | +------+ 3 rows in set (0.050 sec)结果显示表
tbl2中已导入数据。
使用旁路导入将表 tbl1 中的数据导入到其他表中。
创建表
tbl1。obclient [SYS]> CREATE TABLE tbl1(c1 int);插入数据到表
tbl1。obclient [SYS]> INSERT INTO tbl1 VALUES (1),(2),(3);查询表
tbl1中的数据。obclient [SYS]> SELECT * FROM tbl1;查询结果如下:
+------+ | C1 | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (0.045 sec)使用旁路导入将表
tbl1中数据导入到表tbl2。指定
CREATE TABLE AS SELECT语句的 Hint。使用
APPENDHint 旁路导入数据。obclient [SYS]> CREATE /*+ append parallel(4) */ TABLE tbl2 AS SELECT * FROM tbl1;使用
DIRECTHint 旁路导入数据。obclient [SYS]> CREATE /*+ direct(true, 0, 'full') parallel(4) */ TABLE tbl2 AS SELECT * FROM tbl1;
不指定
CREATE TABLE AS SELECT语句的 Hint。设置
default_load_mode的值为FULL_DIRECT_WRITE。obclient [SYS]> ALTER SYSTEM SET default_load_mode ='FULL_DIRECT_WRITE';obclient [SYS]> CREATE TABLE tbl2 AS SELECT * FROM tbl1;
验证表
tbl2中是否已导入数据。obclient [SYS]> SELECT * FROM tbl2;查询结果如下:
+------+ | C1 | +------+ | 3 | | 2 | | 1 | +------+ 3 rows in set (0.013 sec)结果显示表
tbl2中已导入数据。