, , )划分工作单位。
是 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:检查任务拆分状态
可以确认分割时每个 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:检查并发执行状态(任务执行前)
如果在执行任务之前通过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:检查并发执行状态(任务运行中)
让我们按工作划分的块(而不是按会话)检查进度。
-- 작업의 Chunk별 진행상황/완료 확인
SELECT *
FROM USER_PARALLEL_EXECUTE_CHUNKS
WHERE TASK_NAME = 'DPE_TEST(BY ROWID)';
第 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:按块状态检查进度
从上面的结果中,您可以看到有 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;
/
第四步:确认任务完成并删除任务
如果执行DROP_TASK后再次检查USER_PARALLEL_EXECUTE_TASKS视图,可以确认该任务已被删除。
到目前为止,我们已经了解了 ROWID 分区并行处理任务的一个简单案例。
接下来我们看一下ROWID划分的工作单元的统一程度如何,是否有遗漏,以及chunk数量和job数量之间的相关性(并行度)如何。
标签: 甲骨文 DBMS_PARALLEL_EXECUTE 并行处理 DML 并行处理 DML 并行处理
我使用 DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_ROWID 执行它,但是当我查看任务状态时,我看到 NO_CHUNKS。你能告诉我为什么吗?
我测试的环境是Oracle 11g R2(11.2),当时没有NO_CHUNKS状态。
我进行了谷歌搜索并发现了以下内容:
———————————–
NO_CHUNKS:与任务关联的表没有创建块
———————————–
* 来源:Oracle 19c 文档
https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/DBMS_PARALLEL_EXECUTE.html#GUID-5581516D-AB22-4748-8476-C5BB38BE7E2F
当块按ROWID划分,但该chunk内的所有块都没有数据时,它似乎处于NO_CHUNKS状态。
最近没有使用过Oracle,所以测试起来比较困难。
请将此仅供参考。