暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

分布式数据库学习Note42:OceanBase社区版中,并行 DML 如何理解?

并行 DML 通过使用并行执行机制来提高对大型数据库的表和索引执行插入、更新、删除等操作,以提高执行效率。对于决策支持系统 (DSS)的数据库,并行 DML 提供了查询和更新功能,是对并行查询功能的补充。对于 OLTP 数据库,并行 DML 操作可以加速批处理作业的运行。

开启和关闭并行 DML

OceanBase 数据库支持在 SQL 语句或会话中显式启用并行 DML。

在 SQL 语句中启用和关闭并行 DML

在 SQL 语句中启用并行 DML,请在语句中插入如下 Hint:

/*+ ENABLE_PARALLEL_DML PARALLEL(3) */ 

一般情况下,ENABLE_PARALLEL_DML Hint 和 PARALLEL Hint 必须配合使用才能开启并行 DML。不过,当目标表的 Schema 上指定了表级别的并行度时,仅需指定 ENABLE_PARALLEL_DML Hint。

如下示例为同时使用 ENABLE_PARALLEL_DML Hint 和 PARALLEL(n) 参数指定并行度 n,并且 n > 1,并行度 dop=2

CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT) NOPARALLEL;
CREATE TABLE t2 (c1 INT PRIMARY KEY, c2 INT) PARALLEL 11 PARTITION BY HASH(c1) PARTITIONS 3;
CREATE TABLE t3 (c1 INT PRIMARY KEY, c2 INT) PARALLEL 10 PARTITION BY HASH(c1) PARTITIONS 4;
obclient> EXPLAIN INSERT /*+ ENABLE_PARALLEL_DML PARALLEL(2) */  INTO t1 SELECT * FROM T3\G
*************************** 1. row ***************************
==============================================================
|ID|OPERATOR                       |NAME    |EST. ROWS|COST  |
--------------------------------------------------------------
|0 |PX COORDINATOR                 |        |400000   |537675|
|1 | EXCHANGE OUT DISTR            |:EX10001|400000   |537675|
|2 |  INSERT                       |        |400000   |537675|
|3 |   EXCHANGE IN DISTR           |        |400000   |482466|
|4 |    EXCHANGE OUT DISTR (RANDOM)|:EX10000|400000   |302612|
|5 |     SUBPLAN SCAN              |VIEW1   |400000   |302612|
|6 |      PX BLOCK ITERATOR        |        |400000   |247403|
|7 |       TABLE SCAN              |T3      |400000   |247403|
==============================================================

Outputs & filters:
-------------------------------------
  0 - output(nil), filter(nil)
  1 - output(nil), filter(nil), dop=2
  2 - output(nil), filter(nil),
      columns([{T1: ({T1: (T1.C1, T1.C2)})}]), partitions(p0), conv_exprs([column_conv(NUMBER,PS:(38,0),NOT NULL,VIEW1.C1)], [column_conv(NUMBER,PS:(38,0),NULL,VIEW1.C2)])
  3 - output([column_conv(NUMBER,PS:(38,0),NOT NULL,VIEW1.C1)], [column_conv(NUMBER,PS:(38,0),NULL,VIEW1.C2)]), filter(nil)
  4 - output([column_conv(NUMBER,PS:(38,0),NOT NULL,VIEW1.C1)], [column_conv(NUMBER,PS:(38,0),NULL,VIEW1.C2)]), filter(nil), dop=2
  5 - output([column_conv(NUMBER,PS:(38,0),NOT NULL,VIEW1.C1)], [column_conv(NUMBER,PS:(38,0),NULL,VIEW1.C2)]), filter(nil),
      access([VIEW1.C1], [VIEW1.C2])
  6 - output([T3.C1], [T3.C2]), filter(nil)
  7 - output([T3.C1], [T3.C2]), filter(nil),
      access([T3.C1], [T3.C2]), partitions(p[0-3])
1 row in set

如果要禁用并行 DML,请在语句中插入如下 Hint:

/*+ DISABLE_PARALLEL_DML */

即使会话中启用了并行 DML,您也可以在指定 SQL语句中使用 DISABLE_PARALLEL_DML Hint 禁用并行PDML。

在会话中启用和关闭并行 DML

默认情况下,即使 SQL语句中使用了 PARALLEL Hint,并行 DML 也是不开启的,所以还需要通过在会话上开启并行 DML。在会话中启用并行 DML,请运行以下 SQL 语句:

set _force_parallel_dml_dop = 3

说明

当 _force_parallel_dml_dop 被修改为大于 1 时,当前 session 上的 DML 都会以大于 1 的并行度执行,当 _force_parallel_query_dop 被修改为 1 时,当前 session 上的 DML 则不开启并行执行。

如下示例为在会话中开启并行 DML。

CREATE TABLE t1 (C1 NUMBER(38) PRIMARY KEY, C2 NUMBER(38)) NOPARALLEL;
CREATE TABLE t2 (C1 NUMBER(38) PRIMARY KEY, C2 NUMBER(38)) PARALLEL 11 PARTITION BY HASH(C1) PARTITIONS 3;
CREATE TABLE t3 (C1 NUMBER(38) PRIMARY KEY, C2 NUMBER(38)) PARALLEL 10 PARTITION BY HASH(C1) PARTITIONS 4;
obclient> set  _force_parallel_dml_dop = 6;
Query OK, 0 rows affected 

obclient> EXPLAIN INSERT INTO t2 SELECT * FROM t3\G
*************************** 1. row ***************************
===================================================================
|ID|OPERATOR                            |NAME    |EST. ROWS|COST  |
-------------------------------------------------------------------
|0 |PX COORDINATOR                      |        |400000   |537675|
|1 | EXCHANGE OUT DISTR                 |:EX10001|400000   |537675|
|2 |  INSERT                            |        |400000   |537675|
|3 |   EXCHANGE IN DISTR                |        |400000   |482466|
|4 |    EXCHANGE OUT DISTR (PKEY RANDOM)|:EX10000|400000   |302612|
|5 |     SUBPLAN SCAN                   |VIEW1   |400000   |302612|
|6 |      PX BLOCK ITERATOR             |        |400000   |247403|
|7 |       TABLE SCAN                   |T3      |400000   |247403|
===================================================================

Outputs & filters:
-------------------------------------
  0 - output(nil), filter(nil)
  1 - output(nil), filter(nil), dop=6
  2 - output(nil), filter(nil),
      columns([{T2: ({T2: (T2.C1, T2.C2)})}]), partitions(p[0-2]), conv_exprs([column_conv(NUMBER,PS:(38,0),NOT NULL,VIEW1.C1)], [column_conv(NUMBER,PS:(38,0),NULL,VIEW1.C2)])
  3 - output([column_conv(NUMBER,PS:(38,0),NOT NULL,VIEW1.C1)], [column_conv(NUMBER,PS:(38,0),NULL,VIEW1.C2)], [PARTITION_ID]), filter(nil)
  4 - (#keys=1, [column_conv(NUMBER,PS:(38,0),NOT NULL,VIEW1.C1)]), output([column_conv(NUMBER,PS:(38,0),NOT NULL,VIEW1.C1)], [column_conv(NUMBER,PS:(38,0),NULL,VIEW1.C2)], [PARTITION_ID]), filter(nil), dop=6
  5 - output([column_conv(NUMBER,PS:(38,0),NOT NULL,VIEW1.C1)], [column_conv(NUMBER,PS:(38,0),NULL,VIEW1.C2)]), filter(nil),
      access([VIEW1.C1], [VIEW1.C2])
  6 - output([T3.C1], [T3.C2]), filter(nil)
  7 - output([T3.C1], [T3.C2]), filter(nil),
      access([T3.C1], [T3.C2]), partitions(p[0-3])
1 row in set

需要注意的是,在 SQL 语句中启用并行 DML 时,一般使用由 Hint 指定的并行度来执行查询,其优先级高于会话中强制指定的并行度。示例如下:

CREATE TABLE t1 (C1 NUMBER(38) PRIMARY KEY, C2 NUMBER(38)) NOPARALLEL;
CREATE TABLE t2 (C1 NUMBER(38) PRIMARY KEY, C2 NUMBER(38)) PARALLEL 11 PARTITION BY HASH(C1) PARTITIONS 3;
CREATE TABLE t3 (C1 NUMBER(38) PRIMARY KEY, C2 NUMBER(38)) PARALLEL 10 PARTITION BY HASH(C1) PARTITIONS 4;
obclient> set  _force_parallel_dml_dop = 6;
Query OK, 0 rows affected 

obclient> EXPLAIN INSERT /*+ PARALLEL(3) */ INTO t2 SELECT * FROM t3\G
*************************** 1. row ***************************
===================================================================
|ID|OPERATOR                            |NAME    |EST. ROWS|COST  |
-------------------------------------------------------------------
|0 |PX COORDINATOR                      |        |400000   |537675|
|1 | EXCHANGE OUT DISTR                 |:EX10001|400000   |537675|
|2 |  INSERT                            |        |400000   |537675|
|3 |   EXCHANGE IN DISTR                |        |400000   |482466|
|4 |    EXCHANGE OUT DISTR (PKEY RANDOM)|:EX10000|400000   |302612|
|5 |     SUBPLAN SCAN                   |VIEW1   |400000   |302612|
|6 |      PX BLOCK ITERATOR             |        |400000   |247403|
|7 |       TABLE SCAN                   |T3      |400000   |247403|
===================================================================

Outputs & filters:
-------------------------------------
  0 - output(nil), filter(nil)
  1 - output(nil), filter(nil), dop=3
  2 - output(nil), filter(nil),
      columns([{T2: ({T2: (T2.C1, T2.C2)})}]), partitions(p[0-2]), conv_exprs([column_conv(NUMBER,PS:(38,0),NOT NULL,VIEW1.C1)], [column_conv(NUMBER,PS:(38,0),NULL,VIEW1.C2)])
  3 - output([column_conv(NUMBER,PS:(38,0),NOT NULL,VIEW1.C1)], [column_conv(NUMBER,PS:(38,0),NULL,VIEW1.C2)], [PARTITION_ID]), filter(nil)
  4 - (#keys=1, [column_conv(NUMBER,PS:(38,0),NOT NULL,VIEW1.C1)]), output([column_conv(NUMBER,PS:(38,0),NOT NULL,VIEW1.C1)], [column_conv(NUMBER,PS:(38,0),NULL,VIEW1.C2)], [PARTITION_ID]), filter(nil), dop=3
  5 - output([column_conv(NUMBER,PS:(38,0),NOT NULL,VIEW1.C1)], [column_conv(NUMBER,PS:(38,0),NULL,VIEW1.C2)]), filter(nil),
      access([VIEW1.C1], [VIEW1.C2])
  6 - output([T3.C1], [T3.C2]), filter(nil)
  7 - output([T3.C1], [T3.C2]), filter(nil),
      access([T3.C1], [T3.C2]), partitions(p[0-3])
1 row in set

如果要禁用并行 DML,请运行以下 SQL 语句:

set  _force_parallel_dml_dop = 1;

禁用并行 DML 时,即使在 SQL 语句中使用 PARALLEL Hint,也不会执行并行 DML。 在会话中启用并行 DML 时,则并行执行对此会话中的所有 DML 语句都会生效。如果 SQL 语句通过 ENABLE_PARALLEL_DML Hint 启用并行 DML 时,则并行执行仅对指定语句生效。但是,如果没有具有并行属性的表,或者违反了并行操作的限制,即使启用了并行 DML,DML 操作仍然会串行执行。

使用说明

OceanBase 数据库支持如下 SQL 语句的并行执行能力:

  • INSERT INTO SELECT
  • UPDATE
  • DELETE

如果表上存在下列索引类型,则需要支持并行执行:

  • 局部索引
  • 单分区全局索引
  • 多分区全局索引

OceanBase 数据库不支持以下 SQL 语句使用并行 DML:

  • REPLACE
  • MERGE INTO
  • INSERT INTO ON DUPLICATE KEY UPDATE
  • 不支持多表 DML 语句

如果表上存在如下属性,也不支持并行 DML:

  • 触发器
  • 外键
  • CHECK 约束
  • 唯一索引
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论