Java Jdbc减少与Oracle之间交互提升批量处理性能,到底该如何优化才好?
不拾掇Java有好几年了(N>3吧),之所以写这篇文章其实是纯粹是为了给开发人员一些好的使用jdbc真正去减少交互和提升批量处理batch update性能的例子; 如果你是DBA,那么工作之余你可以把这篇文章推荐给开发看一下, 也许这些例子他已经知道了, 倘若他不知道,那么也算一种福利了。能考虑到在应用程序client和 数据库服务器DB server间减少交互时间,批量更新处理的绝对是有助于重构和优化代码的好同志; 但这种优化一定要注意方法,如果是自行去重新发明一种轮子的话, 效果往往是不如人意的。例如Tom Kytes曾在他的著作里提到这样2个例子,他去协助开发的2家企业的在研发应用的过程中,分别通过应用程序自己去在Oracle中实现了user profile和advanced queue的功能, 有一定经验的朋友肯定会知道这2样功能其实Oracle Enterprise Edition企业版软件都是原生态支持的,而自己在DB中去实现它们,最终结果自然是项目的失败。类似的有朋友在开发过程中,为了优化Oracle JDBC中的批量更新update操作,想到了这样的方式,例如要插入INSERT 15000行数据,则在JAVA层面 将15000条INSERT语句拼接在一个PL/SQL block里,这15000条SQL涉及到的变量仍使用PreparedStatement.setXXX方法带入,其在JAVA层面的SQL STRING,如:begin--我是一个拼接起来的SQL匿名块insert into insertit values(?,?,?,?);insert into insertit values(?,?,?,?);insert into insertit values(?,?,?,?);insert into insertit values(?,?,?,?);insert into insertit values(?,?,?,?);insert into insertit values(?,?,?,?);insert into insertit values(?,?,?,?);insert into insertit values(?,?,?,?);insert into insertit values(?,?,?,?);insert into insertit values(?,?,?,?);insert into insertit values(?,?,?,?);insert into insertit values(?,?,?,?);.....................commit ; end;如上15000个INSERT拼接成一个PL/SQL block,一次性PreparedStatement.execute()提交给DB,通过这样来减少Jdbc Thin Client与DB Server之间的交互。先不说别的,光在JAVA里循环控制拼接SQL的写法多少是要花点时间的。这种写法和 JDBC里PreparedStatement.setExecuteBatch、或者PreparedStatement+addBatch()+executeBatch()的执行效率究竟如何呢?我们在一个简单的JAVA程序里测试这三者写法的实际性能,并窥探其在DB中的表现,以下为JAVA代码(多年不写,就勿纠结代码风格):/** To change this template, choose Tools | Templates* and open the template in the editor.*/package apptest;import oracle.jdbc.*;import java.sql.*;/**** @author xiangbli*/public class Apptest {/*** @param args the command line arguments*/public static void main(String[] args) throws SQLException {// TODO code application logic heretry {Class.forName("oracle.jdbc.driver.OracleDriver");}catch(Exception e){}Connection cnn1=DriverManager.getConnection("jdbc:oracle:thin:@192.168.56.101:1521:cdb1", "c##maclean", "oracle");Statement stat1=cnn1.createStatement();cnn1.setAutoCommit(false);ResultSet rst1=stat1.executeQuery("select * from v$version");while(rst1.next()){System.out.println(rst1.getString(1));}long startTime = System.currentTimeMillis();long stopTime = System.currentTimeMillis();String str="begin \n --我是一个拼接起来的SQL匿名块 \n";int i;for(i=0;i<=15000; i++){str= str.concat(" insert into insertit values(?,?,?,?); \n");}str=str.concat(" commit ; end; ");System.out.print(str);cnn1.createStatement().execute("alter system flush shared_pool");System.out.print("\n alter system flush shared_pool 已刷新共享池,避免SQL游标缓存 影响第一次测试 \n");PreparedStatement pstmt = cnn1.prepareStatement(str);int j;for (j=0;j<=15000;j++){pstmt.setInt(1+j*4, 1);pstmt.setInt(2+j*4, 1);pstmt.setInt(3+j*4, 1);pstmt.setInt(4+j*4, 1);}// System.out.println (" Statement Execute Batch Value " +((OraclePreparedStatement)pstmt).getExecuteBatch());startTime = System.currentTimeMillis();pstmt.execute();stopTime = System.currentTimeMillis();System.out.println("拼接15000条INSERT SQL 第一次运行的耗时 Elapsed time was " + (stopTime - startTime) + " miliseconds.");startTime = System.currentTimeMillis();pstmt.execute();stopTime = System.currentTimeMillis();System.out.println("拼接15000条INSERT SQL 第二次运行的耗时 Elapsed time was " + (stopTime - startTime) + " miliseconds.");cnn1.createStatement().execute("alter system flush shared_pool");System.out.print("\n alter system flush shared_pool 已刷新共享池,避免SQL游标缓存 影响第二次测试 \n");startTime = System.currentTimeMillis();int batch=1000;PreparedStatement pstmt2 = cnn1.prepareStatement("insert into insertit values(?,?,?,?)");((OraclePreparedStatement)pstmt2).setExecuteBatch(batch);for (int z=0;z<=15000;z++){pstmt2.setInt(1, z);pstmt2.setInt(2, z);pstmt2.setInt(3, z);pstmt2.setInt(4, z);pstmt2.executeUpdate();}((OraclePreparedStatement)ps补充:软件开发 , Java ,
上一个:单独hibernate 生成表
下一个:java实现u盘指定内容的自动复制
- 更多Oracle疑问解答:
- 运行exp备份oracle数据库提示oracle-12154错误
- 有没有,生产Oracle Rman 备份脚本的工具啊!
- 初学orcle,希望有大大帮忙解说一下详细步骤,从登录oracle到创建表的过程
- oracle语句问题:一张user表,三个字段,id,name,time,插入记录比如:张三2007,李四2008,张三2011
- 如何写一个ORACLE触发器同步两个表中的数据?
- oracle 如何查看一个服务器上有多少个数据库.
- oracle 创建包的时候错误 求解
- oracle 重复列的问题
- oracle 中如何查处2星期前的数据
- 请教oracle数据库安装中的问题
- 请问谁能提供给我标准的oracle ERP的数据库表结构并详细说明各表主要的作用?
- 安装oracle遇到的问题 invalid entry CRC (expected 0x3e12e795 but got 0x9db0e9fd)
- 我的是ORACLE 10G,在RMAN中如何按指定的时间恢复数据文件啊?
- oracle为什么没有自动增长列
- oracle快捷键都有哪些啊?