一、简介

  ORACLE11g R2版本的新特性之一就是引进了DBMS_PARALLEL_EXECUTE包,使用DBMS_PARALLEL_EXECUTE包批量并行递增式的更新表。

  更多ORACLE11g新特性请参考:http://www.cnblogs.com/oracle-dba/articles/3632223.html
基本原理:
  (1) 把数据集分割成小的块(chunk),可基于rowid进行分块,也可根据指定范围的行数(rows)进行分块。
  (2) 在每一个块上以并行的方式应用update语句,在每个块执行完成后,立即提交,原理是通过调用JOB进行并发操作。
好处在于:
  (1) 在执行update操作时,仅仅锁住一个chunk而非锁住整个表;
  (2) 因为对每个chunk 执行完毕就提交,所以当update操作失败后,之前变更的并不会回滚;
  (3) 减小回滚空间(undo)的使用;
  (4) 提高性能,可根据服务器的性能设置chunk_size与parallel_level的大小。
备注:parallel_level取决于CPU的个数,以及parallel_threads_per_cpu。

DBMS_PARALLEL_EXECUTE 使用三种将一个表的数据分割成多个chunk的方法:
  (1) CREATE_CHUNKS_BY_NUMBER_COL : 通过指定的字段来切割表
  (2) CREATE_CHUNKS_BY_ROWID : 通过ROWID来切割表,本文只介绍通过BY ROWID 进行分割
  (4) CREATE_CHUNKS_BY_SQL : 通过用户提供的sql语句来切割表

二、实践操作

  DBMS_PARALLEL_EXECUTE这个包操作起来比较简单,大体步骤为:

  (1)创建任务task,即调用create_task()过程;

  (2)创建分块规则,即调用create_chunk_by_rowid()或者create_chunk_by_number_col()等过程;

  (3)写动态update的sql语句,复杂和简单的均可,可以通过dbms_output.put_line()来验证动态sql的正确性;

  (4)运行task任务,即调用run_task()过程;

  (5)监控task任务,可通过视图user_parallel_execute_tasks和user_parallel_execute_chunks来监控task状态;

  (6)task成功运行完毕后,将任务删除,即调用drop_task()过程。

 2.1 准备工作

   给用户授权

    调用dbms_parallel_execute包时,需要有执行create job的权限,因此需要给用于赋予create job权限。

      grant create job to username;

   也可把grant execute on dbms_scheduler to username;赋予某用户。

 2.2 写代码

   实践操作代码,有改动,仅做参考。

CREATE OR REPLACE PROCEDURE Pro_Parallel_Exec_Update(i_Taskid IN VARCHAR2,
--任务ID 传入是序列 para_task_seq.nextval
i_Inputdate IN DATE,
--日期
i_Tabname IN VARCHAR2,
--更新表名
i_Column IN VARCHAR2,
--更新列名
i_Tasktp IN VARCHAR2 DEFAULT 'BY ROWID'
-- 任务类型 未启用的,可设置不能类型的 update
-- 如: 如不同类型的分块方法 by rowid , by number_col ,by sql
) IS
/*******************************************************************
PROC_NAME : 并行更新过程,本例采用BY ROWID 方法
EDIT_NAME : zzd @2014-03-26
REQUIREMENT :
1) ORACLE 11g R2 版本
2) DBMS_PARALLEL_EXECUTE
3) OWN CREATE JOB PRIVILEGE eg: GRANT EXECUTE ON DBMS_SCHEDULER TO USER ;
4) SET JOB_QUEUE_PROCESSES
REFERENCE:
(1) USER_PARALLEL_EXECUTE_CHUNKS
(2) USER_PARALLEL_EXECUTE_TASKS
(3) DBMS_PARALLEL_EXECUTE.DROP_TASK(TASK_NAME);
ATTACH :
(1) 分块范围 Chunk_Size 和并行度 Paralle_Level 可以根据服务器性能自行设置
(2) DBMS_PARALLEL_EXECUTE 包三种 (BY ROWID, BY NUMBER_COL ,BY SQL ) 分块方法,原理差不多
(3) 更多说明参考PLSQL Packages and Types Reference_11R2.pdf
********************************************************************/
--- 任务名常量
v_Taskname VARCHAR2(20) := 'UPDATE_TASK';
--- schema常量
v_Schema CONSTANT VARCHAR2(20) := 'USER';
--- rowid范围常量
v_Cksize CONSTANT INT := 8000;
--- 并行度大小
v_Plevel CONSTANT INT := 10;
--- 日期变量
v_Inputdate VARCHAR2(64);
--- 临时动态sql 变量
v_Sql_Stmt VARCHAR2(4000);
--- 临时动态insert_sql 变量
v_Sql_Insert VARCHAR2(4000);
--- 控制尝试运行次数
v_Trynum NUMBER;
--- 返回运行状态
v_Status NUMBER;
BEGIN
v_Trynum := 0;
--- 日期转换
v_Inputdate := 'TO_DATE(''' || To_Char(i_Inputdate, 'YYYY-MM-DD') ||
''',''' || 'YYYY-MM-DD' || ''')';
--- 写日志开始更新
Dbms_Output.Put_Line('开始运行 ' || ' USER = ' || v_Schema ||
' Table_Name= ' || i_Tabname ||
' Update_Column = ' || i_Column || ' 任务类型为: ' ||
i_Tasktp);
--- 注意这里只能用实体表作为临时表,此处称“中间表”否则在创建task 这步会把临时表的数据情况,事务性和会话性临时表均不可以
--- 清空 中间表数据
EXECUTE IMMEDIATE ' Truncate TABLE User_Table_Temp '; -- 注这个是个实体中间表
--- 动态 insert sql 语句
v_Sql_Insert := ' INSERT INTO User_Table_Temp(Table_Name, Status)
SELECT a.Table_Name, a.Status
FROM User_Tables a
WHERE a.Table_Name LIKE ' || '''' ||
' USER_NAME% ' || ''''; --- 执行动态sql
EXECUTE IMMEDIATE v_Sql_Insert;
--- 测试动态sql
Dbms_Output.Put_Line(v_Sql_Insert); --- 创建任务
v_Taskname := v_Taskname || ' _ ' || i_Taskid;
Dbms_Parallel_Execute.Create_Task(v_Taskname); --- 使用 ROWID 进行范围分组
Dbms_Parallel_Execute.Create_Chunks_By_Rowid(Task_Name => v_Taskname,
Table_Owner => Upper(v_Schema),
Table_Name => Upper(i_Tabname),
By_Row => TRUE,
Chunk_Size => v_Cksize); --- 动态update的sql 脚本
v_Sql_Stmt := ' UPDATE /*+ ROWID (dda) */ ' || Upper(i_Tabname) || ' b
SET b.' || i_Column; v_Sql_Stmt := v_Sql_Stmt || ' = (SELECT a.TABLE_NAME|| A.STATUS
FROM User_Table_Temp a
WHERE b. Object_Name' ||
' = a.TABLE_NAME
AND b.Created = ' || v_Inputdate || ') '; v_Sql_Stmt := v_Sql_Stmt || '
WHERE EXISTS (SELECT 1
FROM User_Table_Temp a
WHERE b.Object_Name ' ||
' = a.TABLE_NAME
AND b.Created = ' || v_Inputdate || ')'; v_Sql_Stmt := v_Sql_Stmt || Chr(10) ||
'AND ROWID BETWEEN :Start_Id AND :End_Id '; --- 测试动态SQL
Dbms_Output.Put_Line(v_Sql_Stmt);
--- 执行并行更新
Dbms_Parallel_Execute.Run_Task(Task_Name => v_Taskname,
Sql_Stmt => v_Sql_Stmt,
Language_Flag => Dbms_Sql.Native,
Parallel_Level => v_Plevel);
--- 更新结束
Dbms_Output.Put_Line('完成运行 ' || ' USER = ' || v_Schema ||
' Table_Name= ' || i_Tabname ||
' Update_Column = ' || i_Column || ' 任务类型为: ' ||
i_Tasktp); --- 如果 task任务出差,则恢复它,并重新执行,如此进行尝试两次
v_Status := Dbms_Parallel_Execute.Task_Status(v_Taskname); WHILE (v_Trynum < 2 AND v_Status != Dbms_Parallel_Execute.Finished) LOOP
v_Trynum := v_Trynum + 1;
--- 恢复任务,尝试继续执行
Dbms_Parallel_Execute.Resume_Task(v_Taskname);
--- 获取当前任务状态
v_Status := Dbms_Parallel_Execute.Task_Status(v_Taskname); END LOOP;
-- 更新完毕后,删除此任务
Dbms_Parallel_Execute.Drop_Task(v_Taskname); END Pro_Parallel_Exec_Update;

 三、相关视图

  (1)USER_PARALLEL_EXECUTE_CHUNKS

  (2)USER_PARALLEL_EXECUTE_TASKS

学习dbms_parallel_execute包的更多相关文章

  1. 从零开始学习PYTHON3讲义(十六)(连载完)学习资源包下载

    <从零开始PYTHON3>学习资源包下载 课程连载已经完全结束. 经过整理校对,这里把在课程中出现过的源码和练习答案示例源码全部打包提供下载: https://pan.baidu.com/ ...

  2. Golang学习 - reflect 包

    ------------------------------------------------------------ 在 reflect 包中,主要通过两个函数 TypeOf() 和 ValueO ...

  3. Golang学习 - io 包

    ------------------------------------------------------------ 先说一下接口,Go 语言中的接口很简单,在 Go 语言的 io 包中有这样一个 ...

  4. 透过Extjs学习JavaScript---闭包篇

    目录 一.前言 二.基础讲解 三.知识应用 四.总结 五.常见问题 一.前言 JavaScript设计得最出色的就是它的函数的实现,它几乎接近于完美.我们现在现就来介绍它其中一个功能“闭包”.我们可以 ...

  5. Python学习---模版/包的概念

    1.1. 模块/包的概念 在Python中,一个.py文件就称之为一个模块(Module) 模块一共三种: python标准库 第三方模块 应用程序自定义模块 模块的使用:模块是用来组织函数的 解释器 ...

  6. 学习抓包之如何用Charles实现“刷楼”

    为了获取一些网络中的数据,我们需要掌握抓包技术. Charles是一个 HTTP 代理服务器, HTTP 监视器,反转代理服务器.它允许一个开发者查看所有连接互联网的 HTTP 通信.这些包括Requ ...

  7. Python入门基础学习(模块,包)

    Python基础学习笔记(五) 模块的概念:模块是python程序架构的一个核心概念 每个以拓展名py结尾的python源代码文件都是一个模块 模块名同样也是一个标识符,需要符合标识符的命名规则 在模 ...

  8. 全面学习 Python 包:包的构建与分发

    首发于公众号:Python编程时光 1. 为什么需要对项目分发打包? 平常我们习惯了使用 pip 来安装一些第三方模块,这个安装过程之所以简单,是因为模块开发者为我们默默地为我们做了所有繁杂的工作,而 ...

  9. 《Java4Android》视频学习笔记——包和访问权限(一)

    怎么打包?代码如下 package org.marsdroid; class Test{ public static void main(String args[]){ System.out.prin ...

随机推荐

  1. MVC源码分析 - Action/Result 过滤器执行时机

    前面 的篇章, 解析了Action方法的查找, 以及 Authorize, Action, Result, Error 过滤器的加载时机. 也花了两篇去看授权和错误过滤器的使用. 但是对于 Actio ...

  2. Java队列——Disruptor 的使用

    .什么是 Disruptor  从功能上来看,Disruptor 是实现了“队列”的功能,而且是一个有界队列.那么它的应用场景自然就是“生产者-消费者”模型的应用场合了. 可以拿 JDK 的 Bloc ...

  3. 【nginx笔记】系统参数设置-使Nginx支持更多并发请求的TCP网络参数

    首先,需要修改/etc/sysctl.conf来更改内核参数.例如,最常用的配置: fs.file-max = 999999 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tc ...

  4. JavaScript的3种继承方式

    JavaScript的继承方式有多种,这里列举3种,分别是原型继承.类继承以及混合继承. 1.原型继承 优点:既继承了父类的模板,又继承了父类的原型对象: 缺点:不是子类实例传参,而是需要通过父类实例 ...

  5. [转](SQL Server) Convert a File from utf-8 to ANSI (such as Windows-1252)

    本文转自:https://example-code.com/sql/charset_convert_file_from_utf8_to_ansi.asp CREATE PROCEDURE Chilka ...

  6. angularjs学习第一天笔记

    您好,我是一名后端开发工程师,由于工作需要,现在系统的从0开始学习前端js框架之angular,每天把学习的一些心得分享出来,如果有什么说的不对的地方,请多多指正,多多包涵我这个前端菜鸟,欢迎大家的点 ...

  7. VB.NET的MsgBox

    一.可用按钮(指定消息框显示哪些按钮) MsgBoxStyle.OkOnly = vbOKOnly = 0(确定按钮) MsgBoxStyle.OkCancel = vbOKCancel = 1(确定 ...

  8. PCA算法Python实现

    源代码: #-*- coding: UTF-8 -*- from numpy import * import numpy def pca(X,CRate): #矩阵X每行是一个样本 #对样本矩阵进行中 ...

  9. UML基础 UML对象图解析

    本节向大家介绍一下UML对象图方面的内容,主要包括UML对象图概念介绍,表示法和用途等,希望通过本节的介绍大家对UML对象图有全面的认识,下面让我们一起来学习吧. UML对象图简介 对象图(Objec ...

  10. c# IEnumerable和IEnumerator枚举器

    一 : IEnumerable 公开枚举数,该枚举数支持在非泛型集合上进行简单迭代. IEnumerable是可以枚举的所有非泛型集合的基接口,IEnumerable包含单个方法GetEnumerat ...