Oracle存储过程处理大批量数据性能测试

2023-10-26

通过此次的大批量数据性能测试,还会间接的给大家分享一个知识点,Oracle存储过程如何处理List集合的问题,废话不多说了,老规矩直接上代码!!!

首先要做的,想必大家应该猜到了。。。建表!

create table tab_1
(
       id varchar(100) primary key,
       name varchar(100),
       password varchar(100)
)



第一步:
create or replace type tab_one as object(
       id varchar2(200),
       name varchar2(200),
       password varchar2(200)
)

第二步:

create or replace type tab_ones as table of tab_one

第三步:

create or replace procedure test7(i_orders in tab_ones)
as
orders tab_one;
begin
     FOR idx in i_orders.first..i_orders.count loop
         orders:=i_orders(idx);
         insert into tab_1
         (id,name,password)
         values
         (orders.id,orders.name,orders.password);
     end loop;
     exception when others then
     raise;

end test7;


测试代码:
public static void main(String[] args) throws SQLException {
        Statement stmt = null;
        ResultSet rs = null;
        Connection conn = null;
        try {
          Class.forName(driver);
          conn = DriverManager.getConnection(url,name,password);
          CallableStatement proc = null;
          List<Tab_One_Bean> orderList = new ArrayList<Tab_One_Bean>(); 
          String date=DateUtils.getDate_time();
          System.out.println("开始:"+date); 
          for(int i=0;i<100000;i++){  
              System.out.println("第"+i+"个");
              orderList.add(new Tab_One_Bean("第"+i+"个","新增用户"+i,i+"@126.com"));  
          }
          StructDescriptor recDesc = StructDescriptor.createDescriptor("TAB_ONE", conn);  
          //这里注意下TAB_ONE在创建时是小写但编译后在Types显示的是大写的
          ArrayList<STRUCT> pstruct = new ArrayList<STRUCT>();  
          for (Tab_One_Bean ord:orderList) {                  
              Object[] record = new Object[3];  
              record[0] = ord.getId();  
              record[1] = ord.getName();
              record[2] = ord.getPassword();
              STRUCT item = new STRUCT(recDesc, conn, record);                
              pstruct.add(item);  
          } 
            ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor("TAB_ONES", conn);            
//这里注意下TAB_ONES在创建时是小写但编译后在Types显示的是大写的            
          ARRAY vArray = new ARRAY(tabDesc, conn, pstruct.toArray());
          proc = conn.prepareCall("{call test7(?)}");       
          proc.setArray(1, vArray);                 
          proc.execute();  
          conn.commit();
          System.out.println("开始:"+date+"  结束:"+DateUtils.getDate_time());
        }
        catch (SQLException ex2) {
          ex2.printStackTrace();
        }
        catch (Exception ex2) {
          ex2.printStackTrace();
        }
        finally{
          try {
            if(rs != null){
              rs.close();
              if(stmt!=null){
                stmt.close();
              }
              if(conn!=null){
                conn.close();
              }
            }
          }
          catch (SQLException ex1) {
          }
        }
     }  

【主意点:】
这里写图片描述

我这里测试了100000条数据量,运行结果:
...
第99989个
第99990个
第99991个
第99992个
第99993个
第99994个
第99995个
第99996个
第99997个
第99998个
第99999个
开始:2017-09-08 16:18:07  结束:2017-09-08 16:18:18

最快的一次用了9秒!


**继续优化以上代码:修改的代码,直接注释了**

第一步:【建议使用这种方式】
public class Tab_One_Bean1 implements ORAData{
    private String id;
    private String name;
    private String password;
    public static final String ORACLE_TYPE_NAME = "TAB_ONE";
    protected MutableStruct struct;  
    static int[] sqlType = { OracleTypes.VARCHAR, OracleTypes.VARCHAR,OracleTypes.VARCHAR };  
    static ORADataFactory[] factory = new ORADataFactory[sqlType.length];  
    public Tab_One_Bean1() {  
        struct = new MutableStruct(new Object[sqlType.length], sqlType, factory);  
    }  
    public Tab_One_Bean1(String id,String name,String password){
        this();//注意这里的this()必须加上,不加会报错,具体错误看下面截图
        this.id=id;
        this.name=name;
        this.password=password;
    }
    @Override
    public Datum toDatum(Connection conn) throws SQLException {
        System.out.println("id:"+this.id+" name:"+this.name+" password: "+this.password);
        struct.setAttribute(0, this.id);
        struct.setAttribute(1, this.name);
        struct.setAttribute(2, this.password);
        return struct.toDatum(conn, ORACLE_TYPE_NAME);
    }

}

【注意】这里的this()必须加上,不加会报以下错误:

开始:2017-09-08 16:49:29
id:0个 name:新增用户0 password: 0@126.com
java.lang.NullPointerException
    at com.util.oracleutils.Tab_One_Bean1.toDatum(Tab_One_Bean1.java:32)
    at oracle.sql.STRUCT.toSTRUCT(STRUCT.java:603)
    at oracle.jdbc.oracore.OracleTypeADT.toDatum(OracleTypeADT.java:241)
    at oracle.jdbc.oracore.OracleTypeADT.toDatumArray(OracleTypeADT.java:302)
    at oracle.jdbc.oracore.OracleTypeUPT.toDatumArray(OracleTypeUPT.java:117)
    at oracle.sql.ArrayDescriptor.toOracleArray(ArrayDescriptor.java:1517)
    at oracle.sql.ARRAY.<init>(ARRAY.java:117)
    at com.util.oracleutils.CallableStatementOracleUtils.main(CallableStatementOracleUtils.java:55)

这里写图片描述


public static void main(String[] args) throws SQLException {
        Statement stmt = null;
        ResultSet rs = null;
        Connection conn = null;
        try {
          Class.forName(driver);
          conn = DriverManager.getConnection(url,name,password);
          CallableStatement proc = null;
//        List<Tab_One_Bean> orderList = new ArrayList<Tab_One_Bean>(); 
          List<Tab_One_Bean1> orderList = new ArrayList<Tab_One_Bean1>(); 
          String date=DateUtils.getDate_time();
          System.out.println("开始:"+date); 
          for(int i=0;i<100000;i++){  
//            System.out.println("第"+i+"个");
//            orderList.add(new Tab_One_Bean("第"+i+"个","新增用户"+i,i+"@126.com"));  
          orderList.add(new Tab_One_Bean1("第"+i+"个","新增用户"+i,i+"@126.com"));
          }
//        StructDescriptor recDesc = StructDescriptor.createDescriptor("TAB_ONE", conn);  //这里注意下TAB_ONE在创建时是小写但编译后在Types显示的是大写的
//        ArrayList<STRUCT> pstruct = new ArrayList<STRUCT>();  
//        for (Tab_One_Bean ord:orderList) {                  
//            Object[] record = new Object[3];  
//            record[0] = ord.getId();  
//            record[1] = ord.getName();
//            record[2] = ord.getPassword();
//            STRUCT item = new STRUCT(recDesc, conn, record);                
//            pstruct.add(item); 
//        }             
          ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor("TAB_ONES", conn);//这里注意下TAB_ONES在创建时是小写但编译后在Types显示的是大写的            
          //ARRAY vArray = new ARRAY(tabDesc, conn, pstruct.toArray());
          ARRAY vArray = new ARRAY(tabDesc, conn, orderList.toArray());
          proc = conn.prepareCall("{call test7(?)}");       
          proc.setArray(1, vArray);                 
          proc.execute();  
          conn.commit();
          System.out.println("开始:"+date+"  结束:"+DateUtils.getDate_time());
        }
        catch (SQLException ex2) {
          ex2.printStackTrace();
        }
        catch (Exception ex2) {
          ex2.printStackTrace();
        }
        finally{
          try {
            if(rs != null){
              rs.close();
              if(stmt!=null){
                stmt.close();
              }
              if(conn!=null){
                conn.close();
              }
            }
          }
          catch (SQLException ex1) {
          }
        }
     }  


继续测试10万条数据,运行结果:
开始:2017-09-08 16:56:32
开始:2017-09-08 16:56:32  结束:2017-09-08 16:56:42


还有一种批量处理的方法进行和存储过程方法对比下哈:
public static void main(String[] args) throws SQLException {
        Statement stmt = null;
        ResultSet rs = null;
        Connection conn = null;
        try {
            Class.forName(driver);
            conn = DriverManager.getConnection(url, name, password);

            String date = DateUtils.getDate_time();
            System.out.println("开始:" + date);
            List<String> lis = new ArrayList<>();
            for (int i = 0; i < 10000; i++) {
                lis.add("insert into tab_1 (id,name,password)values('第" + i + "位','新增用户" + i + "','" + i + "@126.com')");
            }
            conn.setAutoCommit(false);
            pst = conn.createStatement();
            for (int i = 0; i < lis.size(); i++) {
                System.out.println("第:" +i);
                pst.addBatch(lis.get(i).toString());
            }
            pst.executeBatch();
            conn.commit();
            System.out.println("开始:" + date + "  结束:" + DateUtils.getDate_time());
        } catch (SQLException ex2) {
            ex2.printStackTrace();
        } catch (Exception ex2) {
            ex2.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                    if (stmt != null) {
                        stmt.close();
                    }
                    if (conn != null) {
                        conn.close();
                    }
                }
            } catch (SQLException ex1) {
            }
        }
    }
运行结果:
...
第:9990
第:9991
第:9992
第:9993
第:9994
第:9995
第:9996
第:9997
第:9998
第:9999
开始:2017-09-08 17:52:24  结束:2017-09-08 17:53:46


使用addBatch()方法批量处理数据测试10000条数据用时82秒!
存储过程10000条数据用时1秒!!!
存储过程再次测试100000条数据用时8秒!!!

我的技术群这里给大家分享下:472148690 问题可以在群里咨询

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Oracle存储过程处理大批量数据性能测试 的相关文章

随机推荐

  • Attribute application@appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from

    程序在编译时报错 在执行合并AndroidMainfest时报Attribute application appComponentFactory value android support v4 app CoreComponentFacto
  • Property ‘xxx‘ does not exist on type ‘xxx‘报错解决

    用ts写一个组件的时候 遇到了Property increment does not exist on type Add 的红点儿报错 但神奇的是竟然还能正常运行 在参考一些正确的代码后 有两个解决方案 在export default cl
  • P1048 采药(C++)---01背包(动态规划)解题

    题目描述 辰辰是个天资聪颖的孩子 他的梦想是成为世界上最伟大的医师 为此 他想拜附近最有威望的医师为师 医师为了判断他的资质 给他出了一个难题 医师把他带到一个到处都是草药的山洞里对他说 孩子 这个山洞里有一些不同的草药 采每一株都需要一些
  • MathJax 3 配置和上手渲染数学公式及在Vue中的使用

    mathjax是一个用于latex mathml和ascimath表示法的开源javascript显示引擎 mathjax的3 0版是对mathjax的彻底重写 实现了组件化 可以实现不同需求的定制 使用和配置与mathjax2版本有很大的
  • 【redis】Redis cluster是AP架构还是CP架构?

    最近刚好在看CAP理论 加上之前分析的redis cluster 就在想redis的cluster是什么模式的 AP还是CP 首先还是简单讲下CAP 具体的可见 CAP分别是 强一致性 Consistency 可用性 Availabilit
  • 地址栏参数隐藏

    1 result type 的redirectAction改为chain 但要注意如果是登录方法 权限拦截器中就可能会影响 2 将参数放到作用域中 比如session 注意 1 这样的注释是没用的
  • 网络编程13——epoll事件模型:ET和LT模、掌握实现epoll的ET模式(非阻塞模式

    epoll是linux下多路复用IO select poll 的增强版本 它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率 因为它会复用文件描述符集合来传递结果为不用迫使开发者每次等待事件之前都必须重新准备要被侦听的文
  • shiro认证机制及认证原理

    转自 shiro认证机制 认证原理 下文笔者将讲述shiro的认证机制及认证原理 如下所示 Shiro认证 验证用户身份的过程 在认证过程中 用户需要提交实体信息 Principals 和凭据信息 Credentials 以检验用户是否合法
  • 【玩转PointPillars】Ubuntu18.04上部署nutonomy/second.pytorch

    系统环境 Ubuntu18 04 cuda10 2 GeForce GTX 1650 今天部署的项目虽然名称上叫做second pytorch 实际上是PointPillars的作者fork自SECOND项目 并作了改动之后形成的Point
  • 词法分析器构造工具Flex基础学习

    Flex是一个生成词法分析器的工具 它可以利用正则表达式来生成匹配相应字符串的C语言代码 其语法格式基本同Lex相同 单词的描述称为模式 Lexical Pattern 模式一般用正规表达式进行精确描述 FLEX通过读取一个有规定格式的文本
  • SVN 服务器发送了意外的返回值(405 Method Not Allowed),在响应 “MKCOL” 的请求

    先转载一段网上说的解决方法 svn 405 Method Not Allowed 在响应 MKCOL 的请求 I managed to solve the problem Delete the parent s directory of t
  • jupyter lab的目录调整及默认浏览器设置为chrome

    Jupyter lab 的目录调整及默认浏览器设置为chrome 1 Jupyter 默认目录调整 首先要找到jupyter生成的配置文件 jupyter notebook config py 如果没有 在 anaconda prompt
  • 在Anaconda中快速安装OpenCV for Python

    一 下载和安装Anaconda Anaconda下载地址 Anaconda Individual EditionAnaconda s open source Individual Edition is the easiest way to
  • 【吐血整理】java程序员推荐轻薄笔记本

    正文 在写这个文章之前 我花了点时间 自己臆想了一个电商系统 基本上算是麻雀虽小五脏俱全 我今天就用它开刀 一步步剖析 我会讲一下我们可能会接触的技术栈可能不全 但是够用 最后给个学习路线 Tip 请多欣赏一会 每个点看一下 看看什么地方是
  • kali Linux自带firefox ESR设置代理

    1 打开kali的火狐浏览器 找到右上角的 三个杠 在点击 preferences 2 general gt network proxy gt setting 3 打开靶场和burp suite工具 注意火狐浏览器的代理是启动状态 靶场地址
  • 双写绕过的原理

    可以看到代码对key进行了过滤 那怎么办呢 可以构造kekeyy 当key被过滤掉时 剩下的字符自动拼接在一起 就形成了key 所以说 这样就可以拿下flag了
  • 梯度下降(学习笔记)

    应用 梯度下降法 Gradient Descent 又称最速下降法 是迭代法的一种 可用于求解机器学习算法的模型参数 即无约束优化问题 具体来讲可用来求解损失函数的最小值 也可求解最小二乘问题 分类 批量梯度下降 BGD 使用全部样本构建了
  • 职场大佬常用工具:Baklib,一款个人知识笔记管理神器

    又到了大家喜爱的好用工具推荐环节 今天我要给大家推荐一款个人知识笔记管理神器 不出你们所料 它就是Baklib 言归正传那Baklib究竟能干啥呢 引用官网的一句话来说 Baklib工具可以将大家日常工作学习中 存储到电脑 云盘上的文档 知
  • 06makefile学习之三个自动变量($@,$^,$<),模式规则和静态模式规则

    06makefile学习之三个自动变量 lt 和模式规则 以下为相关makefile的学习文章 01makefile学习之GCC编译的四个阶段 带编译阶段 汇编阶段 S c的区别 02makefile学习之makefile的基本原则 03m
  • Oracle存储过程处理大批量数据性能测试

    通过此次的大批量数据性能测试 还会间接的给大家分享一个知识点 Oracle存储过程如何处理List集合的问题 废话不多说了 老规矩直接上代码 首先要做的 想必大家应该猜到了 建表 create table tab 1 id varchar