首页 > 数据库 >https://www.modb.pro/db/1717179181560324096 --转载 Oracle 批量更新(BULK)优化技巧

https://www.modb.pro/db/1717179181560324096 --转载 Oracle 批量更新(BULK)优化技巧

时间:2023-10-27 11:11:06浏览次数:38  
标签:www 21 -- pro object dbms SQL cpu name

面对一个需要更新大量数据的任务,我平时的处理方法是通过循环,每N行提交来完成这个任务。这样做的两个主要原因:

  • 1、频繁地提交大量小事务比处理和提交一个大事务更快,也更高效
  • 2、没有足够的UNDO空间

    今天在学到了一种新的解决思路,在此记录一下方便后面使用。
      假设我们有一个表T,行数很多,现在我们想为所有行更新一列的值,操作如下:

    SQL> set line 800 pagesize 900
  • SQL> set timing on
  • SQL> set time on 21:21:24
  • SQL> set serveroutput on 21:06:41
  • SQL> create table t as select * from all_objects; 21:09:36
  • SQL> exec dbms_stats.gather_table_stats(user,'T'); 21:09:59
  • SQL> variable n number; 21:11:35 SQL> exec :n := dbms_utility.get_cpu_time; 21:12:02 SQL> update t set object_name=lower(object_name); 100932 rows updated. 21:21:39 SQL> exec dbms_output.put_line((dbms_utility.get_cpu_time-:n)||' cpu hses...'); 237 cpu hses...
    • 注:dbms_utility.get_time函数返回当前CPU时间和Wall-clock时间的差值,单位为1/100秒。需要将其转换为毫秒值,即除以10。

    示例1:循环+更新100条数据提交(常规逻辑)

    begin for x in (select rowid rid,object_name, rownum r from t) loop update t set object_name = lower(x.object_name) where rowid = x.rid; if ( mod(x.r,100)=0) then commit; end if; end loop; commit; end; / PL/SQL procedure successfully completed. Elapsed: 00:00:03.37 21:36:23 SQL> exec dbms_output.put_line((dbms_utility.get_cpu_time-:n)||' cpu hses...'); 336 cpu hses... PL/SQL procedure successfully completed.

    示例2:优化写法(Bulk Collect)

    21:45:22 SQL> exec :n := dbms_utility.get_cpu_time; declare type ridArray is table of rowid; type vcArray is table of t.object_name%type; l_rids ridArray; l_names vcArray; cursor c is select rowid,object_name from t; begin open c; loop fetch c bulk collect into l_rids,l_names limit 100; forall i in 1 .. l_rids.count update t set object_name = lower(l_names(i)) where rowid = l_rids(i); commit; exit when c%notfound; end loop; close c; end; / 21:45:13
  • SQL> exec dbms_output.put_line((dbms_utility.get_cpu_time-:n)||' cpu hses...'); 243 cpu hses...

      从CPU的消耗中可以看出第二种方法比第一种方法要的很高的性能提升。使用Bulk Collect进行批量检索,会将检索结果一次性绑定到一个集合变量中,而不是通过游标一条一条的检索处理。可以在SELECT INTO、FETCH INTO、RETURNING INTO语句中使用BULK COLLECT。这些语句大大减少了上下文切换次数(一次切换多次执行),同时提高DML性能。

    • 语法如下:
    SELECT 字段列表 BULK COLLECT INTO var_collect FROM 表名 WHERE 条件;
    • ar_collect:集合变量(联合数组等),用来存放查到的结果

标签:www,21,--,pro,object,dbms,SQL,cpu,name
From: https://www.cnblogs.com/zclzc/p/17791808.html

相关文章

  • (打标签)文件名空格和下划线的转换,指定数量的单元为下划线,剩下的是空格
    importosdefcount_a(filename):"""统计文件名中的a的数量,其中a是空格或下划线"""returnsum(1forcharinfilenameifcharin['_',''])defparse_a_range(a_range):"""解析a范围输入,并返回所有a的索引""&q......
  • 机器学习——多层感知机
    线性模型的局限性例如,线性意味着单调假设:任何特征的增大都会导致模型输出的增大(如果对应的权重为正),或者导致模型输出的减小(如果对应的权重为负)。有时这是有道理的。例如,如果我们试图预测一个人是否会偿还贷款。我们可以认为,在其他条件不变的情况下,收入较高的申请人比收入较......
  • C++的std::move与std::forward原理总结
    目录0、左值与右值的理解左值和右值的概念左值引用和右值引用1.std::move1.1函数原型1.2参数讨论1.3通用引用1.4返回值1.5std::move的常用例子1.5.1用于vector添加值1.5.2用于unique_ptr传递1.6再说转移对象控制权2.std::foward参考阅读大型的C++开源项目代码,基本......
  • 上传文件导致vs调试终止的问题
    最近碰到上传文件后,后台的vs调试自动终止的问题,postman则不会,百思不得其解。最后找到一篇文章(VS上传图片就终止调试问题_输出被调试程序截断_mike0127的博客-CSDN博客)解决了我的问题。 点击VS【工具】-【选项】-【项目和解决方案】-【Web项目】将【在浏览器窗口关闭时停止调试......
  • CF777A题解
    分析发现操作\(6\)次后就会回到初状态,于是将状态打表,将\(n\bmod6\)即可。代码#include<iostream>usingnamespacestd;constexprintMAXN(1000007);inta[6][3]={ {0,1,2}, {1,0,2}, {1,2,0}, {2,1,0}, {2,0,1}, {0,2,1}};intn,k;inli......
  • php 金额格式胡
    //转换不彻底functionExchangeMoney($N_money){$A_tmp=explode(".",$N_money);//将数字按小数点分成两部分,并存入数组$A_tmp$I_len=strlen($A_tmp[0]);//测出小数点前面位数的宽度if($I_len%3==0){$I_step=$I_len/3;//如前面位数的宽度mod3=0,可按,......
  • 获取配置json地址
    //加载配置文件varconfigurationBuilder=newConfigurationBuilder();//添加配置文件路径configurationBuilder.SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json");//获取Url信息varconfiguration=configurationBuilder.Build();stringname......
  • 最近学习到的一些linux的常用命令
    1、ls命令可以列出当前目录下的内容清单。它与windows下的dir命令很像 2、cd命令这个命令可以改变目录cd~  //更改到本用户的主目录cddesktop //更改目录到desktop cd.. //更改目录到上一级 3、管道输出可以把shell命令输出到文件里面ls>somefile.tx......
  • PPA简介
    PPA,即PersonalPackageArchive(个人软件包档案),是Ubuntu系统中一个用于存储和分发软件包的在线仓库。PPA的主要功能PPA允许开发人员和维护人员将软件包上传到Launchpad(https://launchpad.net/)(一个由CanonicalLtd提供支持的项目和代码托管平台),从而让用户能够轻松地安装和更新......
  • 金蝶KIS VB插件 老单据如何插入多行值,老单获取基础资料内码、代码、名称
    转自:https://blog.csdn.net/ssyyll/article/details/16804273WhileNotrs.EOF '填充对应的行 Withm_BillTransfer '如果超过两行以上的值,需要先用 .BillForm.InsertRow '插入一行 .SetGridTextLRow,dicFieldEntry("FItemID"),rs("FNumber") .SetGridText......