`
cruiser_31
  • 浏览: 4913 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
社区版块
存档分类
最新评论

不要迷信技术,不完全测试java+sybase在预编译与否的情况下,插入sql语句的性能

阅读更多
测试环境:
    JAVA的运行平台为本机,直接使用eclipse来运行,数据库环境为一台已弃置的公司IBM服务器,系统为AIX,上面常年就只运行数据库这样一个应用。

测试背景:
    由于看到《疯狂JAVA讲义》里面有这样一句“使用PreparedStatement比使用Statement的效率要高”,由于本人经常需要导入成千上万的数据,数据库的效率很大一部分程度上影响我的工作效率,因此就按书上所说的代码进行测试了一下。

测试过程:
    1、先按下面的代码进行了测试,结果如下:
类型/次数(单位毫秒)12345
预编译1465615562158281456215203
非预编译1382815438141721436014781
相差8281241656202442

由上面的结果可知,
预编译都要比非预编译的要慢,平均相差650毫秒,最大竟然相差了1秒多,最少也相差了124毫秒

    2、经过了上述测试之后,现打算先运行预编译的,然后再运行非预编译(就是调换一下insertUsePrepare和insertUseStatement方法的顺序),如下:
类型/次数(单位毫秒)12345
预编译1718814734165161498415141
非预编译1414013500137181715614093
相差304812342798-21721048

预编译除了有一次跑赢非预编译之外,其他时间都比非预编译的慢,而且差距还是挺大的。

    3、经过上面两次测试之后,分析了一下语句。会不会是预编译的时候运行setString方法耗费的时间比较长,特意测试了一下该方法耗用的时间占比
类型/次数(单位毫秒)12345
预编译耗时2742215500151561500015547
setString耗时12493233155143
占比(%)4.5.61.51.0.9

从这次测试可知,setString方法耗费的时间大概为150左右,为第一二个测试的几分之一至十几分之一。对影响不大,就是说setString耗费的时间并不是造成预编译sql运行效率更加低下的原因。

重写的insertUsePrepare方法
	public void insertUsePrepare()throws Exception
	{
		long start = System.currentTimeMillis();
		long addStringtime=0;
		try
		{
			//使用Connection来创建一个PreparedStatment对象
			pstmt = conn.prepareStatement("insert into student_table(student_name,java_teacher) values(?,1)");
			//100次为PreparedStatement的参数设置,就可以插入100条记录
			for (int i = 0; i < 10000 ; i++ )
			{
				long start2 = System.currentTimeMillis();
				pstmt.setString(1 , "姓名" + i);
				addStringtime+=System.currentTimeMillis()-start2;
				pstmt.executeUpdate();
			}
			System.out.println("使用PreparedStatement费时:" + (System.currentTimeMillis() - start));
			System.out.println("使用PreparedStatement并接字费时:" + addStringtime);
		}
		//使用finally块来关闭数据库资源
		finally
		{
			if (pstmt != null)
			{
				pstmt.close();
			}
		}

	}


总结:造成这种现象的原因还不清楚,希望有牛人能够解释的了。不过也从侧面说明,不一定需要迷信。所谓的预编译sql语句运行效率更高不一定在所有的情况中都正确的。笔者另外做了几个测试,在插入十笔这种数量级的情况下,预编译与否性能差不多;插入100笔的时候,情况跟《疯狂JAVA讲义》相类似,预编译的比较快;插入1万笔的时候,笔者测试了两笔,预编译的要多耗时4%;插入十万笔的时候,笔者也测试了两笔,预编译的就明显要快一点,快大概6%。不过不得说一句,Sybase,对你很无语。

测试程序:
主测试程序(从《疯狂JAVA讲义》里面的有所修改)
package qm.test.qm.test;

import java.sql.Statement;
import java.sql.Connection;
import java.sql.PreparedStatement;

import qm.khcx.datacon.Sybase4_76;
import qm.tools.system.Logs;

/**
 * 测试预编译的sql和没有预编译的sql语句在插入sybase数据库的性能
 */
public class PreparedStTest {
	protected static Sybase4_76 database = new Sybase4_76("Sybase4_76.ini");
	private static Connection conn;
	private Statement stmt;
	private PreparedStatement pstmt;
	private static Logs log = new Logs();

	/**
	 * 主调用程序
	 */
	public static void main(String[] args) {
		PreparedStTest pt = new PreparedStTest();
		try
		{
			conn = database.getCon();
			pt.insertUseStatement();
			pt.insertUsePrepare();
		}catch(Exception e){
		    log.write("连接数据库出错:"+e.getMessage());
		}
	}

	/**
	 * 插入没有预编译的sql语句
	 * @throws Exception
	 */
	public void insertUseStatement()throws Exception
	{
		long start = System.currentTimeMillis();
		try
		{
			//使用Connection来创建一个Statment对象
			stmt = conn.createStatement();
			//需要使用100条SQL语句来插入100条记录
			for (int i = 0; i < 10000 ; i++ )
			{
				stmt.executeUpdate("insert into student_table(student_name,java_teacher) values('姓名"	+ i + "',1)");
			}
			System.out.println("使用Statement费时:" + (System.currentTimeMillis() - start));
		}
		//使用finally块来关闭数据库资源
		finally
		{
			if (stmt != null)
			{
				stmt.close();
			}
		}
	}

	/**
	 * 插入预编译的sql语句
	 * @throws Exception
	 */
	public void insertUsePrepare()throws Exception
	{
		long start = System.currentTimeMillis();
		try
		{
			//使用Connection来创建一个PreparedStatment对象
			pstmt = conn.prepareStatement("insert into student_table(student_name,java_teacher) values(?,1)");
			//100次为PreparedStatement的参数设置,就可以插入100条记录
			for (int i = 0; i < 10000 ; i++ )
			{
				pstmt.setString(1 , "姓名" + i);
				pstmt.executeUpdate();
			}
			System.out.println("使用PreparedStatement费时:" + (System.currentTimeMillis() - start));
		}
		//使用finally块来关闭数据库资源
		finally
		{
			if (pstmt != null)
			{
				pstmt.close();
			}
		}

	}
}


类Sybase4_76(用于管理sybase数据库的连接和关闭)
package qm.khcx.datacon;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.ResultSet;
import java.io.FileInputStream;
import java.io.File;
import java.util.Properties;
import qm.tools.system.Logs;

/**
 * 用于连接182.53.4.76服务器上的khcx数据库
 *
 * @author 顾启明
 *
 */
public class Sybase4_76 {
	/** driverClassName 数据库驱动 */
	private String driverClassName;
	/** driverClassName 数据库地址、端口和数据名称 */
	private String url;
	/** driverClassName 数据库用户名 */
	private String user;
	/** driverClassName 数据库密码 */
	private String pass;
	protected Connection connection;
	private Logs log = new Logs();
	
	/**
	 * 构造方法,设置数据库地址、端口等信息
	 * @param paramFile 数据库配置文件名
	 */
	public Sybase4_76(String paramFile){
		try{
			//使用Properties类来加载属性文件
			Properties props = new Properties();
			props.load(new FileInputStream(paramFile));
			driverClassName = props.getProperty("driver");
			url = props.getProperty("url");
			user = props.getProperty("user");
			pass = props.getProperty("pass");
		}catch(Exception e){
			log.write("文件出错:"+e.getMessage());
        }
	}
	
	/**
	 * 获得数据库连接
	 * @return 连接
	 */
	public Connection getCon(){   
        try {
        	//加载数据库驱动
        	Class.forName(driverClassName);
        	//获取数据库连接
            connection = DriverManager.getConnection(url, user, pass);
            log.write(connection);
        }catch (Exception e) {
			log.write("连接数据库出错:"+e.getMessage());
        }
        return connection;
	}
	
	/**
	 * 关闭数据库连接
	 * @return 连接
	 */
	public void closeCon(){   
        try {
        	//加载数据库驱动
        	connection.close();
        	connection = null;
        	log.write("连接已关闭");
        }catch (Exception e) {
			log.write("连接数据库出错:"+e.getMessage());
        }
	}
	
	public static void main(String[] args) throws Exception{
		File file = new File(".");
		System.out.println(file.getAbsolutePath());
		// TODO Auto-generated method stub
		Sybase4_76 test = new Sybase4_76("Sybase4_76.ini");
		//System.out.println(test.getCon());
		try{
			System.out.println("1");
			Statement st = test.getCon().createStatement();
			System.out.println("2");
			ResultSet rs = st.executeQuery("select count(*) as con from TRADE_JL_TMP");
			while(rs.next()){
				System.out.println("3");
				System.out.println(rs.getInt("con"));
			}
		}catch(Exception e){
			System.out.println("4");
			System.out.println(e.getMessage());
		}finally{
			test.closeCon();
		}
		
	}
}


类Logs(用于记录日志,以备以后扩充之用)
package qm.tools.system;

public class Logs {
	public void write(Object input){
		System.out.println(input);
	}
}


数据库配置文件"Sybase4_76.ini"
driver=com.sybase.jdbc3.jdbc.SybDriver
url=jdbc:sybase:Tds:<ip地址>:<端口号>/<数据库名称>
user=<用户名>
pass=<密码>


student_table建表语句
create table dbo.student_table (
   student_id           numeric(18)                    identity,
   student_name         varchar(255)                   null,
   java_teacher         numeric(18)                    not null,
   constraint student_ta_studen_19993431561 primary key (student_id)
         on "default"
)
0
0
分享到:
评论

相关推荐

    WEB性能测试结果分析及调优.pptx

    在进行 WEB 性能测试结果分析时,常见的误区包括:扩大服务器的配置、缺乏适当的方法或策略、迷信专家或秘籍、缺乏独立思考等。 2. WEB 性能测试结果分析的误区原因 WEB 性能测试结果分析的误区原因包括:硬件故障...

    切莫迷信测试软件一颗让老鸟抓狂的神秘处理器.pdf

    标题中的“切莫迷信测试软件一颗让老鸟抓狂的神秘处理器”暗示了本文可能讨论的是在处理器评测和性能分析中,过于依赖测试软件可能导致的误导性结果,以及某些特定处理器可能带来的挑战。这些测试软件可能包括CPU...

    液晶市场“屏”成焦点不要过于迷信原装

    一方面,有些消费者过分迷信原装面板,即使在经济条件不允许的情况下,也愿意购买合资品牌的低端产品。但行业人士指出,这并非明智之举,因为合资品牌的低端产品几乎不可能保持面板原装,同时这个价格也足以购买到...

    只给大模型LeetCode编号,也能解题!大模型表现好是源于对训练数据的记忆吗?请不要迷信大模型.pdf

    研究发现,模型在没有完整任务描述的情况下仍能成功解题,可能是因为它在训练时接触过类似的任务。例如, Codex(ChatGPT的前身之一)在只知道任务编号的情况下,依然能够提供解题思路,但如果仅改变任务目标,其...

    ORACLE学习心得

    在这个过程中,不应迷信于未经验证的理论,而是要亲自测试和验证,挑战既定的观念。 阅读《Expert Oracle Programming》这样的专业书籍是深入理解Oracle的好方法。在开发Oracle数据库应用程序时,关注数据库的体系...

    软件测试人员与开发人员的相处之道

    - **测试技术并不高深**:并非所有开发人员都精通测试技巧,但这并不意味着他们不能成为优秀的测试者。通过培训和支持,开发人员可以在短时间内掌握基本的测试技能。 #### 开发人员需要理解测试人员 同样地,开发...

    只给大模型LeetCode编号,也能解题!大模型表现好是源于对训练数据的记忆吗?请不要迷信大模型

    在经过训练后,它们能够理解和生成人类语言,甚至在某些情况下表现出超越人类的性能。然而,当大模型面对编程问题时,其“解题”能力可能并非基于真正理解代码和算法,而是因为它们在训练过程中接触了大量的代码片段...

    从C++到Java,10年技术生涯的几点思考

    从算法上讲我认为毫无疑问是汇编〉C++〉Java,不要迷信某些个别评测,单纯的回圈测试什么的,比如JNode的官方网站上有Java写的JVM的性能和SUN的JVM进行性能比较的结果,JNode中用Java写的JVM竟然能比SUN公司用C++写...

    小学政治相信科学不迷信教学设计.docx

    【小学政治相信科学不迷信教学设计】 这是一份专门针对小学政治科目的教学设计文档,旨在帮助学生理解和接受科学知识,摒弃迷信观念。教学设计的核心目标是培养学生的认知、情感和行为三个层面: 1. 认知目标: -...

    手机号码选择工具,可测试吉凶,娱乐工具,含源码

    标题中的“手机号码选择工具,可测试吉凶”是一个基于数字迷信的娱乐应用,它可能通过某种算法或规则为用户提供手机号码的“吉凶”分析。这类应用通常并不基于科学,而是利用人们的信仰和好奇心来设计。源码的提供...

    对自由贸易的迷信.doc

    然而,该理论假设的是完全竞争市场,而现实中市场往往存在不完全竞争和规模报酬递增的情况。以克鲁格曼为代表的新国际贸易理论揭示了这些因素对贸易模式的影响,指出非自由贸易政策有时可能更优。 自由贸易政策的一...

    Java实现的树以及包含树的内存缓存框架

    不要迷信redis,现在webserver本身的内存也很大的,充分利用嘛。 怎么用?参考下面的代码。 treeCacher = new TreeCacher, SysModule&gt;(new ITreeCacheQueryer, SysModule&gt;() { @Override public List&lt;SysModule&gt; ...

    小学政治:相信科学不迷信(教学方案).pdf

    小学政治:相信科学不迷信(教学方案).pdf

    不要迷信找最好的人,要找最合适的人-马云.JPG

    不要迷信找最好的人,要找最合适的人-马云.JPG

    初中语文文摘社会请君入瓮除迷信

    迷信在很多情况下是人们对未知世界的恐惧和不安的产物,它往往缺乏科学依据,但能够深深植根于人们的思想中。对待迷信,我们不仅要保持批判性思维,勇于质疑,还要善于运用智慧去揭示其荒谬之处。故事中的小孩就是一...

    申万宏源_20160901_技术指标测试大全——微卡片1——介绍.pdf

    ### 技术指标测试全集概览 #### 一、项目背景及意义 申万宏源研究所金融工程部推出的《技术指标测试全集》旨在深入探究金融市场上常用的40多种技术指标的投资效果,并通过参数优化得出最佳应用方案。该项目基于...

    智能素质测评创新能力测试.docx

    如问题5和15询问测试者是否不迷信权威和在解决问题时能保持兴奋。根据回答数量,可以判断出创造力的强弱,20个“V”代表极强的创造力,16-13个“V”表示良好的创造力,10个或以下“V”则意味着创造力一般。 **测试...

    魏小李windowsphone UI常见问题及性能优化.pdf

    Tile图片应当在任何情况下都能清晰显示。 3. 性能优化: - 内存优化:合理管理内存使用,避免内存泄漏和不必要的内存消耗。 - 数据加载:优化数据绑定性能,合理分解UI线程与工作线程的使用,避免UI线程进行耗时...

Global site tag (gtag.js) - Google Analytics