2. ROWID分区方法并行处理案例(DBMS_PARALLEL_EXECUTE)

让我们看一下使用 Oracle DBMS_PARALLEL_EXECUTE 进行 ROWID 分区并行处理的情况。

这是上一篇文章的延续。

1. DML任务中的并行性概述(DBMS_PARALLEL_EXECUTE)

2. ROWID划分法并行处理案例

2.1.创建 ROWID 分区并行处理作业

创建任务( ) 创建任务。

-- 1단계: 작업생성
BEGIN
  ​​DBMS_PARALLEL_EXECUTE.CREATE_TASK(TASK_NAME => 'DPE_TEST(BY ROWID)');
END;
/

就业创造的结果可以如下检查。

-- 작업 생성 확인
SELECT * FROM USER_PARALLEL_EXECUTE_TASKS;
1단계: 작업 생성 확인
步骤1:确认任务创建

从上面的结果中,可以看到Task已经创建完毕,并且STATUS为CREATED。

作为参考,任务的 STATUS 有以下值:CHUNKED、CHUNKING、CHUNKING_FAILED、CRASHED、CREATED、FINISHED、FINISHED_WITH_ERROR 和 PROCESSING,其含义如下。

  • CHUNKED:块已创建,但尚未分配给任务
  • CHUNKING:创建块
  • CHUNKING_FAILED:创建块时失败。
  • CRASHED:任务执行过程中,发生数据库崩溃或作业进程崩溃,错误未被记录并终止。
  • REATED:任务已创建(块尚未创建)
  • FINISHED:所有块均已完成且没有错误
  • FINISHED_WITH_ERROR:所有块已完成,但发生了一些错误
  • PROCESSING:Tosk 已开始执行,部分块正在进行或已完成。

* 参考: http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_parallel_ex.htm#ARPLS67333

2.2.拆分工作单元

CREATE_CHUNKS_BY_ROWID( ,

,
, , )划分工作单位。

是 BOOLEAN 类型,如果为 TRUE表示行计数,如果为 FALSE 则表示块计数。

要创建将 Z_DPE_TEST_TAB 表的行数划分为 10,000 行的块,请执行以下操作。

-- 2단계: 작업 단위 분할
BEGIN
  DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_ROWID(TASK_NAME   => 'DPE_TEST(BY ROWID)',
                                               TABLE_OWNER => USER,
                                               TABLE_NAME  => 'Z_DPE_TEST_TAB',
                                               BY_ROW      => TRUE,
                                               CHUNK_SIZE  => 10000);
END;
/

我们来看看工作单位的分工情况。

-- 작업 분할 상태 확인
SELECT *
  ​​FROM USER_PARALLEL_EXECUTE_CHUNKS
 ​WHERE TASK_NAME = 'DPE_TEST(BY ROWID)';
2단계: 작업 분할 상태 확인
步骤2:检查任务拆分状态

可以确认分割时每个 chunk 的 STATUS 都是 UNASSIGNED。作为参考,chunk的STATUS有值UNASSIGNED、ASSIGNED、PROCESSED和PROCESSED_WITH_ERROR,每个值的含义如下。

  • UNASSIGNED:块已创建,但尚未分配给任务
  • ASSIGNED:块已分配给任务并正在运行
  • 已处理:操作已完成,没有错误。
  • PROCESSED_WITH_ERROR:任务成功完成,但运行时发生错误。

* 参考: http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_parallel_ex.htm#ARPLS67333

2.3.作业运行

运行任务( , , , )来执行任务。

这里,LANGUAGE_FLAG表示Oracle处理SQL_STMT的标准版本,DBMS_SQL.NATIVE可以用作默认值。

作为参考,Oracle文档的内容如下。

  • V6(或 0)指定版本 6 的行为
  • NATIVE(或 1)指定程序所连接的数据库的正常行为
  • V7(或2)指定Oracle数据库版本7的行为

PARALLEL_LEVEL是指要同时执行的作业的数量,即并行度(DOP),并且可以等于或小于作为工作单元的块的数量。在相同的情况下,一个作业处理一个 chunk,在较小的情况下,一个作业处理多个 chunk。

-- 동시 실행현황 확인: 작업 실행전
SELECT AUDSID, COUNT(*)
  FROM Z_DPE_TEST_TAB
 GROUP BY AUDSID
 ORDER BY AUDSID;
3단계: 동시 실행현황 확인(작업 실행전)
步骤3:检查并发执行状态(任务执行前)

如果在执行任务之前通过AUDSID检查COUNT,可以看到所有数据都被设置为空,并且还没有执行。

现在让我们运行任务。

-- 3단계: 작업 실행
DECLARE
  L_SQL_STMT VARCHAR2(32767);
BEGIN
  L_SQL_STMT := 'UPDATE  Z_DPE_TEST_TAB
                    SET  VAL = ROUND(DBMS_RANDOM.VALUE(1,10000))
                        ,AUDSID = SYS_CONTEXT(''USERENV'',''SESSIONID'')
                  WHERE  ROWID BETWEEN :START_ID AND :END_ID';

  DBMS_PARALLEL_EXECUTE.RUN_TASK(TASK_NAME      => 'DPE_TEST(BY ROWID)',
                                 SQL_STMT       => L_SQL_STMT,
                                 LANGUAGE_FLAG  => DBMS_SQL.NATIVE,
                                 PARALLEL_LEVEL => 10);
END;
/

执行的SQL通过两个绑定变量指定执行范围:START_ID和:END_ID。如果使用不同的变量名称,将会发生错误,因此请务必使用该名称。

出于测试目的,此处执行的 SQL 被编写为更新 VAL 列中的随机值并更新 AUDSID 列中的当前 SESSIONID 值,以检查哪个会话更新了当前行。

作为参考,AUDSID 列与 V$SESSION.AUDSID 具有相同的含义。如果每个chunk单元操作耗时较长,可以通过AUDSID查找V$SESSION来进行会话监控。

如果在执行过程中运行以下 SQL,则可以检查哪些会话中正在更新多少行。

-- 동시 실행현황 확인: 작업 실행중
SELECT AUDSID, COUNT(*)
  FROM Z_DPE_TEST_TAB
 GROUP BY AUDSID
 ORDER BY AUDSID;
3단계: 동시 실행현황 확인(작업 실행중)
步骤3:检查并发执行状态(任务运行中)

让我们按工作划分的块(而不是按会话)检查进度。

-- 작업의 Chunk별 진행상황/완료 확인
SELECT *
  FROM USER_PARALLEL_EXECUTE_CHUNKS
WHERE TASK_NAME = 'DPE_TEST(BY ROWID)';
3단계: 작업의 Chunk별 진행상황/완료 확인
第 3 步:检查每个工作块的进度/完成情况

从上面的结果可以看到STATUS变成了PROCESSED,并且START_TS(开始时间)和END_TS(结束时间)都被管理了。

要按块状态检查进度,请执行以下 SQL。

-- Chunk의 상태별 진행상황
SELECT STATUS, COUNT(*)
  FROM USER_PARALLEL_EXECUTE_CHUNKS
 WHERE TASK_NAME = 'DPE_TEST(BY ROWID)'
GROUP BY STATUS;
3단계: Chunk의 상태별 진행상황 확인
步骤 3:按块状态检查进度

从上面的结果中,您可以看到有 172 个块以 PROCESSED 状态完成。由于图像是在任务完成后捕获的,因此只记录了一种状态。如果任务耗时较长,可以通过状态查看 chunk 数量。

2.4.确认任务完成并删除

删除任务( ) 删除任务。

作为参考,如果不删除它,稍后创建具有相同 TASK_NAME 的任务时将出现 ORA-29497: DUPLICATE_TASK_NAME 错误。

-- 작업 완료 확인
SELECT *
  FROM USER_PARALLEL_EXECUTE_TASKS;
작업 완료 확인
确认任务完成

从上面的结果中,您可以看到任务的 STATUS 为 FINISHED。

-- 4단계: 작업 완료 확인 및 작업 삭제
BEGIN
  DBMS_PARALLEL_EXECUTE.DROP_TASK(TASK_NAME => 'DPE_TEST(BY ROWID)');
END;
/
4 단계: 작업 완료 확인 및 작업 삭제
第四步:确认任务完成并删除任务

如果执行DROP_TASK后再次检查USER_PARALLEL_EXECUTE_TASKS视图,可以确认该任务已被删除。


到目前为止,我们已经了解了 ROWID 分区并行处理任务的一个简单案例。

接下来我们看一下ROWID划分的工作单元的统一程度如何,是否有遗漏,以及chunk数量和job数量之间的相关性(并行度)如何。

2 条回复

  1. 头像照片 newyemac说道:

    我使用 DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_ROWID 执行它,但是当我查看任务状态时,我看到 NO_CHUNKS。你能告诉我为什么吗?

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注