PLSQL_性能优化系列11_Oracle Bulk Collect批处理

简介: 2014-10-04 Created By BaoXinjian 一、摘要 PL/SQL程序中运行SQL语句是存在开销的,因为SQL语句是要提交给SQL引擎处理。 这种在PL/SQL引擎和SQL引擎之间的控制转移叫做上下文却换,每次却换时,都有额外的开销。

2014-10-04 Created By BaoXinjian

一、摘要


PL/SQL程序中运行SQL语句是存在开销的,因为SQL语句是要提交给SQL引擎处理。

这种在PL/SQL引擎和SQL引擎之间的控制转移叫做上下文却换,每次却换时,都有额外的开销。

但是,FORALL和BULK COLLECT可以让PL/SQL引擎把多个上下文却换压缩成一个,这使得在PL/SQL中的要处理多行记录的SQL语句执行的花费时间骤降。

 

1. FORALL与BULK COLLECT的使用方法:

(1). 使用FORALL比FOR效率高,因为前者只切换一次上下文,而后者将是在循环次数一样多个上下文间切换。

(2). 使用BLUK COLLECT一次取出一个数据集合,比用游标条取数据效率高,尤其是在网络不大好的情况下。但BLUK COLLECT需要大量内存。

2. 未使用批处理时,系统需频繁切换上下文

3. 使用批处理后,系统只需切换上下文一次

 

二、批处理 - Bulk Collect


采用BULK COLLECT可以将查询结果一次性地加载到Collections中,而不是通过Cursor一条一条地处理。

可以在Select Into ,Fetch Into,Returning Into语句使用BULK COLLECT。

注意在使用BULK COLLECT时,所有的INTO变量都必须是Collections。

 

1. Select Into 中使用Bulk Collect

DECLARE
   TYPE table_forall IS TABLE OF test_forall%ROWTYPE;
   v_table   table_forall;
BEGIN
   SELECT   mub.user_id, mub.user_name
     BULK   COLLECT
     INTO   v_table
     FROM   mag_user_basic mub
    WHERE   mub.user_id BETWEEN 10000 AND 10100;

   FORALL idx IN 1 .. v_table.COUNT
      INSERT INTO test_forall
        VALUES   v_table (idx);

   --VALUES(v_table(idx).user_id,v_table(idx).user_name);Error
   --在PL/SQL中,BULK In-BIND与RECORD,%ROWTYPE是不能在一块使用的,
   --也就是说,BULK In-BIND只能与简单类型的数组一块使用
   COMMIT;
EXCEPTION
   WHEN OTHERS
   THEN
      ROLLBACK;
END;

 

2. Fetch Into 中使用Bulk Collect

DECLARE
   TYPE table_forall IS TABLE OF test_forall%ROWTYPE;
   v_table   table_forall;

   CURSOR c1
   IS
      SELECT   mub.user_id, mub.user_name
        FROM   mag_user_basic mub
       WHERE   mub.user_id BETWEEN 10000 AND 10100;
BEGIN
   OPEN c1;

   --在fetch into中使用bulk collect
   FETCH c1 BULK COLLECT INTO   v_table;

   FORALL idx IN 1 .. v_table.COUNT
      INSERT INTO test_forall
        VALUES   v_table (idx);

   COMMIT;
EXCEPTION
   WHEN OTHERS
   THEN
      ROLLBACK;
END;

 

3. 在Returning Into中使用Bulk Collect

DECLARE
   TYPE IdList IS TABLE OF test_forall.User_Id%TYPE;
   enums   IdList;
   TYPE NameList IS TABLE OF test_forall.user_name%TYPE;
   names   NameList;
BEGIN
   DELETE FROM   test_forall2
         WHERE   user_id = 10100
     RETURNING   user_id, user_name BULK COLLECT INTO   enums, names;

   DBMS_OUTPUT.put_line ('Deleted ' || SQL%ROWCOUNT || ' rows:');

   FOR i IN enums.FIRST .. enums.LAST
   LOOP
      DBMS_OUTPUT.put_line ('User #' || enums (i) || ': ' || names (i));
   END LOOP;

   COMMIT;
EXCEPTION
   WHEN OTHERS
   THEN
      ROLLBACK;
END;

 

三、批处理 - ForAll


FORALL告诉PL/SQL引擎要先把一个或多个集合的所有成员都绑定到SQL语句中,然后再把语句发送给SQL引擎。

 

1. 批量更新中,将For改成Forall

(1). 使用For语句进行Update

DECLARE
    TYPE NumList IS VARRAY(20) OF NUMBER;
    depts NumList := NumList(10, 30, 70, ...);
    -- department numbers
BEGIN
  ...
  FOR i IN depts.FIRST..depts.LAST
  LOOP
    ...
    --UPDATE statement is sent to the SQL engine
    -- with each iteration of the FOR loop!
    UPDATE emp SET sal = sal * 1.10 WHERE deptno = depts(i);
  END LOOP:
END;

(2). 使用Forall语句的批处理进行Update

--UPDATE statement is sent to the SQL engine just once, with the entire nested table
FORALL i IN depts.FIRST..depts.LAST
UPDATE   emp
   SET   sal = sal * 1.10
 WHERE   deptno = depts (i);

 

Thanks and Regards

参考:http://www.jb51.net/article/35424.htm

参考:http://log-cd.iteye.com/blog/411122


ERP技术讨论群: 288307890
技术交流,技术讨论,欢迎加入
Technology Blog Created By Oracle ERP - 鲍新建
相关文章
|
3月前
|
存储 Java 数据库
JAVAEE框架数据库技术之13_oracle 之PLSQL技术及存储过程和函数(二)
JAVAEE框架数据库技术之13_oracle 之PLSQL技术及存储过程和函数
38 0
|
5月前
|
SQL Oracle 关系型数据库
Oracle21C + PLSQL Developer 15 + Oracle客户端21安装配置完整图文版
Oracle21C + PLSQL Developer 15 + Oracle客户端21安装配置完整图文版
136 0
|
2月前
|
Oracle 关系型数据库 Java
plsql链接远程Oracle数据库步骤
实际工作中,我们往往需要使用 PLSQL Develope 工具连接远程服务器上的 ORACLE 数据库进行管理,但是由于 ORACLE 安装在本地电脑步骤繁琐,并且会耗费电脑的很大一部分资源,因此,我们寻求一种不需要在本地安装 ORACLE 数据库而能直接使用 PLSQL Develope 工具连接到远程服务器 ORACLE 的方法。
41 2
|
3月前
|
存储 SQL Java
JAVAEE框架数据库技术之13_oracle 之PLSQL技术及存储过程和函数(一)
JAVAEE框架数据库技术之13_oracle 之PLSQL技术及存储过程和函数
35 0
|
6月前
|
Oracle 关系型数据库 数据库连接
Windows系统安装配置Oracle数据库连接工具PLSQL
Windows系统安装配置Oracle数据库连接工具PLSQL
|
6月前
|
SQL Oracle 关系型数据库
Oracle连接工具PLSQL登录时提示初始化失败,无法锁定OCI.dll错误解决
Oracle连接工具PLSQL登录时提示初始化失败,无法锁定OCI.dll错误解决
323 0
|
6月前
|
SQL Oracle 关系型数据库
Oracle数据库连接工具PLSQL/Navicat安装与连接环境配置
Oracle数据库连接工具PLSQL/Navicat安装与连接环境配置
|
8月前
|
Oracle 关系型数据库 数据库
PLSQL连接本地oracle或远程oracle数据库,实现随意切换
PLSQL连接本地oracle或远程oracle数据库,实现随意切换
|
9月前
|
SQL 网络协议 Oracle
异地使用PLSQL远程连接访问Oracle数据库【内网穿透】
异地使用PLSQL远程连接访问Oracle数据库【内网穿透】
162 0
|
10月前
|
SQL Oracle 关系型数据库
使用Plsql+oracle client 连接 Oracle数据库
最近刚入职一家做Java开发的公司,公司数据库使用的是Oracle。以前做开发都是用MySQL的,公司里面的同事都在用的数据库工具plsql,口碑不错,也跟着他们来用。刚开始下载安装plsql,连接数据库的时候花费了不少时间呀,踩了很多坑。现在我把我的经验分享给没经验的小伙伴们。
274 0

相关课程

更多

推荐镜像

更多