关于PreparedStatement接口的一个测试

来源:互联网 发布:php websocket详解 编辑:程序博客网 时间:2024/04/30 01:30
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 160x600, 创建于 08-4-23MSDN */google_ad_slot = "4367022601";google_ad_width = 160;google_ad_height = 600;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>

  1.前言

  在一个论坛上,有个朋友曾经说自己做过一个测试,通过PreparedStatement对数据库进行大批量的数据插入与不通过PrepareStatement进行插入相比,在性能上(至少在时间上)没有丝毫优越的地方——相反在一些情况下竟然不如。我几乎没有用到过PrepareStatement接口,但是看到这样的测试结果还是很令我惊讶。为了严谨起见,我们必须通过测试来证实或者证伪这样的论断。

  2.PreparedStatement简介

  在JDK1.4的api文档中,可以找到对PreparedStatement的描述:

  AnobjectthatrepresentsaprecompiledSQLstatement.

  ASQLstatementisprecompiledandstoredinaPreparedStatementobject.Thisobjectcanthenbeusedtoefficientlyexecutethisstatementmultipletimes.

  根据这样的描述我们可以得到这样的印象:设计PreparedStatement是为了提高数据库处理和执行SQL语句的效率。如果起的作用是相反或者没有作用,那么就没有存在的必要。

  当需要对数据库进行数据插入、更新或者删除的时候,程序会发送整个SQL语句给数据库处理和执行。数据库处理一个SQL语句,需要完成解析SQL语句、检查语法和语义以及生成代码;一般说来,处理时间要比执行语句所需要的时间长。

  如果需要发送的SQL语句除了数据改变之外其他都不变——这是经常可以遇见的——假如按照通常的手段,那么数据库还是会重新解析这条语句,做上一次已经做过的事情。如果次数很多,比如上万次,那么重复解析所花费的时间就相当可观了。

  PreparedStatement接口用来把一个SQL语句发送给数据库,让该语句在数据库中得到预处理,然后数据库得到程序发送过去的数据执行相应的操作。程序不断发送数据,而数据库不需要再花费解析的时间就可以执行。

  3.开始测试

  我们采用微软的Access2000建立一个名为db1.mdb的数据库,新建一张名为student的空表,这个表有自动递增的ID字段、name字段、physic字段、maths字段、chinese字段、english字段。

  建立好数据库之后我们着手配置ODBC源,数据源名(DataSourceName)为redsun,LoginName为snow,Password为ookk。

  我们通过两种途径对数据库进行10000条记录插入,第一种是利用普通的Statement接口,第二种通过PreparedStatement接口,然后通过相同的方式记录插入前后的时间差。

  1)通过Statement接口

  Connectioncon;

  Statementsql;

  Stringstr;

  longa,b,abc;

  a=0;

  b=0;

  abc=0;

  str="INSERTINTOstudent(name,physic,maths,chinese,english)VALUES('xiaowang',90,91,93,94)";

  try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");}

  catch(ClassNotFoundExceptione){}

  try

  {

  con=DriverManager.getConnection("jdbc:odbc:redsun","snow","ookk");

  sql=con.createStatement();

  a=System.currentTimeMillis();//记录起始时间

  for(inti=0;i<10000;i++)

  {sql.execute(str);}

  b=System.currentTimeMillis();//记录结束时间

  abc=b-a;

  con.close();

  }

  catch(SQLExceptione1){e1.getMessage();}

  System.out.println(a);

  System.out.println(b);

  System.out.println(abc);

  最后我们得到的时间差为30453毫秒。

  我们将数据库中插入的数据清空,进行第二次测试。

  2.通过PreparedStatment接口

  str2="INSERTINTOstudent(name,physic,maths,chinese,english)VALUES(?,?,?,?,?)";

  try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");}

  catch(ClassNotFoundExceptione){}

  try

  {

  con=DriverManager.getConnection("jdbc:odbc:redsun","snow","ookk");

  PreparedStatementps=con.prepareStatement(str2);

  ps.setString(1,"xiaowang");

  ps.setInt(2,90);

  ps.setInt(3,91);

  ps.setInt(4,93);

  ps.setInt(5,94);

  a=System.currentTimeMillis();//记录起始时间

  for(inti=0;i<10000;i++)

  {

  ps.executeUpdate();

  }

  b=System.currentTimeMillis();//记录结束时间

  abc=b-a;

  con.close();

  }

  catch(SQLExceptione1){e1.getMessage();}

  System.out.println(a);

  System.out.println(b);

  System.out.println(abc);

  我们得到的时间差为13429毫秒,一半的时间还不到,令人惊讶。

  4.总结

  我们对数据库通过两种途径插入相同的数据,所花费的时间差别是显而易见的。

  在进行大批量数据的插入时——很多时候SQL语句中仅仅数据改变——PreparedStatement接口的优越性是无庸置疑的。

<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 160x600, 创建于 08-4-23MSDN */google_ad_slot = "4367022601";google_ad_width = 160;google_ad_height = 600;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
原创粉丝点击