- 浏览: 607764 次
- 性别:
- 来自: 北京
-
最新评论
-
黑色幽默_cool:
这种不负责任的文章,多看一分钟都是浪费。
为什么使用ibatis而不用spring jdbcTemplate -
leibinhui:
不错啊 非常实用
JS正则表达式详解[收藏] -
suu:
写个存储过程,爆如下错误,是不是游标里的数据太多引起的?无法执 ...
使用Spring jdbc template调用Sybase带有返回结果集的储存过程-要点 -
travellers:
有SVR6了,为什么很多还在使用SVR4呢?
什么是SVR4?我们为什么要选择SVR4? -
dotjar:
生活是多么美好阿!
老公日记
从开始写java程序就一直被灌输着一种思想,如果使用jdbc一定要使用PreparedStatement,而不要使用Statement对象。
其中的原因有好多,比如可以防止SQL注入攻击,防止数据库缓冲池溢出,代码的可读性,可维护性。这些都很正确。
但是还有一点人们经常提的就是PreparedStatement能够显著的提高执行效率。
看了两篇关于PreparedStatement和Statement的帖子
http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=121&threadID=10397&start=0&tstart=0
http://www.iteye.com/topic/5631?page=1
里面提到,PreparedStatement并不一定比Statement快,于是想自己动手测试一下
一共分5种情况测试
分析:
第一种情况:
由于我测试时采用jdbc直接链接数据库,所以在第一种情况下插入速度很慢,时间都消耗在了数据库链接的创建上了,符合常理,没什么疑义。
第二种情况:
由于使用Statement插入时sql语句都相同,我通过阅读上面的两篇帖子,猜想可能是Statement语句也被DB缓存了,所以跟
PreparedStatement速度差不多,我想如果每次插入的sql都不同,那么Statement应该慢下来了吧。
第三种情况:
并非像我在执行第二种情况时想象的那样,PreparedStatement还是跟Statement差不多,于是我想是不是数据量不够大呀,于是我增大了
插入数据量,希望PreparedStatement能够比Statement快些
第四/五种情况:
测试结果PreparedStatement反到更慢了。
PreparedStatement什么情况下才会比Statement快?那位大侠来指点一下!
代码如下:
DDL
测试程序
你误解我的意思了。 这个跟junit有什么关系
其中的原因有好多,比如可以防止SQL注入攻击,防止数据库缓冲池溢出,代码的可读性,可维护性。这些都很正确。
但是还有一点人们经常提的就是PreparedStatement能够显著的提高执行效率。
看了两篇关于PreparedStatement和Statement的帖子
http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=121&threadID=10397&start=0&tstart=0
http://www.iteye.com/topic/5631?page=1
里面提到,PreparedStatement并不一定比Statement快,于是想自己动手测试一下
一共分5种情况测试
stmt pre-stmt --1:每次都单独连数据库--100条 21.936 22.076 22.05 22.051 22.172 22.178 --2:Stmt使用相同的SQL语句,参数值也相同--100条 0.78 0.796 0.718 0.749 0.749 0.764 --3:Stmt使用相同的SQL语句,参数值不同--100条 0.967 0.749 0.78 0.874 0.749 0.749 --4:Stmt使用相同的SQL语句,参数值也相同--10000条 33.079 36.154 34.156 39.306 34.359 36.138 --5:Stmt使用相同的SQL语句,参数值不同--10000条 32.799 34.125 32.564 35.53 35.701 34.952 32.582 40.798 38.893 42.345 35.082 41.736
分析:
第一种情况:
由于我测试时采用jdbc直接链接数据库,所以在第一种情况下插入速度很慢,时间都消耗在了数据库链接的创建上了,符合常理,没什么疑义。
第二种情况:
由于使用Statement插入时sql语句都相同,我通过阅读上面的两篇帖子,猜想可能是Statement语句也被DB缓存了,所以跟
PreparedStatement速度差不多,我想如果每次插入的sql都不同,那么Statement应该慢下来了吧。
第三种情况:
并非像我在执行第二种情况时想象的那样,PreparedStatement还是跟Statement差不多,于是我想是不是数据量不够大呀,于是我增大了
插入数据量,希望PreparedStatement能够比Statement快些
第四/五种情况:
测试结果PreparedStatement反到更慢了。
PreparedStatement什么情况下才会比Statement快?那位大侠来指点一下!
代码如下:
DDL
CREATE TABLE dbo.jdbc_stmt ( id numeric(10,0) IDENTITY, name varchar(10) NOT NULL, grad int NOT NULL, age int NOT NULL, dept int NOT NULL )
测试程序
public void jdbcStmtPerformance() { //1:每次都单独连数据库--100条 // String stmtSQL = "insert into jdbc_stmt values('ivanl',2,25,1001)"; // for(int i = 0; i< 100; i++) // { // logger.debug("stmt #"+i); // getJdbcTemplate().update(stmtSQL); // } //2:Stmt使用相同的SQL语句,参数值也相同--100条 // getJdbcTemplate().execute(new StatementCallback(){ // public Object doInStatement(Statement stmt) throws SQLException // { // String stmtSQL = "insert into jdbc_stmt values('ivanl',2,25,1001)"; // for(int i = 0; i< 100; i++) // { // logger.debug("stmt #"+i); // stmt.executeUpdate(stmtSQL); // } // return null; // } // }); //3:Stmt使用相同的SQL语句,参数值不同--100条 // getJdbcTemplate().execute(new StatementCallback(){ // public Object doInStatement(Statement stmt) throws SQLException // { // String stmtSQL = "insert into jdbc_stmt values('ivanl',2,25,"; // for(int i = 0; i< 100; i++) // { // logger.debug("stmt #"+i); // stmt.executeUpdate(stmtSQL+i+")"); // } // return null; // } // }); // 4:Stmt使用相同的SQL语句,参数值也相同--10000条 // getJdbcTemplate().execute(new StatementCallback(){ // public Object doInStatement(Statement stmt) throws SQLException // { // String stmtSQL = "insert into jdbc_stmt values('ivanl',2,25,1001)"; // for(int i = 0; i< 10000; i++) // { // logger.debug("stmt #"+i); // stmt.executeUpdate(stmtSQL); // } // return null; // } // }); // 5:Stmt使用相同的SQL语句,参数值不同--10000条 getJdbcTemplate().execute(new StatementCallback(){ public Object doInStatement(Statement stmt) throws SQLException { String stmtSQL = "insert into jdbc_stmt values('ivanl',2,25,"; for(int i = 0; i< 10000; i++) { logger.debug("stmt #"+i); stmt.executeUpdate(stmtSQL+i+")"); } return null; } }); } public void jdbcPreStmtPerformance() { //1:每次都单独连数据库--100条 // String stmtSQL = "insert into jdbc_stmt values(?,?,?,?)"; // for(int i = 0; i< 100; i++) // { // logger.debug("pre-stmt #"+i); // getJdbcTemplate().update(stmtSQL, new Object[]{"ivanl", new Integer(2), new Integer(25), new Integer(1002)}); // } //2:Stmt使用相同的SQL语句,参数值也相同--100条 // String stmtSQL = "insert into jdbc_stmt values(?,?,?,?)"; // getJdbcTemplate().execute(stmtSQL,new PreparedStatementCallback(){ // public Object doInPreparedStatement(PreparedStatement ps) throws SQLException // { // for(int i = 0; i< 100; i++) // { // logger.debug("pre-stmt #"+i); // ps.setString(1, "ivanl"); // ps.setInt(2, 2); // ps.setInt(3, 25); // ps.setInt(4, 1002); // ps.execute(); // } // return null; // } // }); //3:Stmt使用相同的SQL语句,参数值不同--100条 // String stmtSQL = "insert into jdbc_stmt values(?,?,?,?)"; // getJdbcTemplate().execute(stmtSQL,new PreparedStatementCallback(){ // public Object doInPreparedStatement(PreparedStatement ps) throws SQLException // { // for(int i = 0; i< 100; i++) // { // logger.debug("pre-stmt #"+i); // ps.setString(1, "ivanl"); // ps.setInt(2, 2); // ps.setInt(3, 25); // ps.setInt(4, i); // ps.execute(); // } // return null; // } // }); //4:Stmt使用相同的SQL语句,参数值也相同--10000条 // String stmtSQL = "insert into jdbc_stmt values(?,?,?,?)"; // getJdbcTemplate().execute(stmtSQL,new PreparedStatementCallback(){ // public Object doInPreparedStatement(PreparedStatement ps) throws SQLException // { // for(int i = 0; i< 10000; i++) // { // logger.debug("pre-stmt #"+i); // ps.setString(1, "ivanl"); // ps.setInt(2, 2); // ps.setInt(3, 25); // ps.setInt(4, 1002); // ps.execute(); // } // return null; // } // }); //5:Stmt使用相同的SQL语句,参数值不同--10000条 String stmtSQL = "insert into jdbc_stmt values(?,?,?,?)"; getJdbcTemplate().execute(stmtSQL,new PreparedStatementCallback(){ public Object doInPreparedStatement(PreparedStatement ps) throws SQLException { for(int i = 0; i< 10000; i++) { logger.debug("pre-stmt #"+i); ps.setString(1, "ivanl"); ps.setInt(2, 2); ps.setInt(3, 25); ps.setInt(4, i); ps.execute(); } return null; } }); }
评论
9 楼
kwang
2007-01-23
楼上的,如果你把Statement st = con.createStatement();
和PreparedStatement pst = con.prepareStatement(psql); 都写在for循环外面,应该就更能看出谁快谁慢了。我在roacle里测了一下,查询5000条数据,PreparedStatement比Statement快一倍。
和PreparedStatement pst = con.prepareStatement(psql); 都写在for循环外面,应该就更能看出谁快谁慢了。我在roacle里测了一下,查询5000条数据,PreparedStatement比Statement快一倍。
8 楼
codeplay
2007-01-23
count大点然后Math.random()*100 换成 Math.random()*10000000结果会不会更明显?
对于prepared stmt和stmt,Oracle应该都缓存其编译后的stmt,缓存100个对它来说太易了
对这个测试来说,所有pre stmt只需要编译一个即可,而stmt只要id不同就得编译
对于prepared stmt和stmt,Oracle应该都缓存其编译后的stmt,缓存100个对它来说太易了
对这个测试来说,所有pre stmt只需要编译一个即可,而stmt只要id不同就得编译
7 楼
LucasLee
2007-01-22
我对PreparedStatement和Statement的性能测试了一下:
测试代码如下:
test表很简单,id int,name varchar(50).
对几种数据库和相应驱动程序进行测试,结果如下(ms):
oracle: 1235 1109
MSSQL2000(JTDS):391 453
MSSQL2000(MS): 453 640
Mysql5: 391 891
PostgreSQL8.1: 1078 1047
结论:
1.单并发情况下,oracle--PostgreSQL--MSSQL--MySQL的性能依次增高;
2.MySQL不支持Prepared Statement特性,已在其驱动程序的文档中证实,所以在MySQL里使用 PreparedStatement的性能尤其低,可以比Statement慢一倍以上。
而MSSQL2000下,PreparedStatement比Statement慢,
Oracle,PostgreSQL对它的支持最好,使用PreparedStatement性能比Statement高。
测试代码如下:
Connection con = getOraConnection(); String sql = "select id,name from test where id="; String tempSql; int count = 1000; long time = System.currentTimeMillis(); for (int i = 0; i < count; i++) { Statement st = con.createStatement(); tempSql=sql+(int) (Math.random() * 100); st.executeQuery(tempSql); st.close(); } System.out.println("st cost:" + (System.currentTimeMillis() - time)); String psql = "select id,name from test where id=?"; time = System.currentTimeMillis(); for (int i = 0; i < count; i++) { int id=(int) (Math.random() * 100); PreparedStatement pst = con.prepareStatement(psql); pst.setBigDecimal(1, new BigDecimal(id)); pst.executeQuery(); pst.close(); } System.out.println("pst cost:" + (System.currentTimeMillis() - time)); con.close();
test表很简单,id int,name varchar(50).
对几种数据库和相应驱动程序进行测试,结果如下(ms):
oracle: 1235 1109
MSSQL2000(JTDS):391 453
MSSQL2000(MS): 453 640
Mysql5: 391 891
PostgreSQL8.1: 1078 1047
结论:
1.单并发情况下,oracle--PostgreSQL--MSSQL--MySQL的性能依次增高;
2.MySQL不支持Prepared Statement特性,已在其驱动程序的文档中证实,所以在MySQL里使用 PreparedStatement的性能尤其低,可以比Statement慢一倍以上。
而MSSQL2000下,PreparedStatement比Statement慢,
Oracle,PostgreSQL对它的支持最好,使用PreparedStatement性能比Statement高。
6 楼
MountLion
2007-01-22
不同类型的数据库对此的优化程度可能是不同的;
单用户状态下和多用户状态下也是不同的。
单用户状态下和多用户状态下也是不同的。
5 楼
LucasLee
2007-01-22
我也怀疑楼主的测试方法。
不过我按我的方法测试了一下,
使用select * from test where id=?的查询,而不是insert。
我在循环里关闭statement。
但每次都是statement快一些。
不过我以前的确用PreparedStatement替代Statement得到了数倍的性能提高,
那时的情况是:字段数量很大,数百个字段(表是自动创建的),单次需要插入数千条记录,
所有使用了批处理。即便都是批处理,此时PreparedStatement还是能快约6倍。
不过我按我的方法测试了一下,
使用select * from test where id=?的查询,而不是insert。
我在循环里关闭statement。
但每次都是statement快一些。
不过我以前的确用PreparedStatement替代Statement得到了数倍的性能提高,
那时的情况是:字段数量很大,数百个字段(表是自动创建的),单次需要插入数千条记录,
所有使用了批处理。即便都是批处理,此时PreparedStatement还是能快约6倍。
4 楼
dengyin2000
2007-01-22
Ivan Li 写道
这两个方法是使用junit分别测试的,使用的不是同一个stmt
你误解我的意思了。 这个跟junit有什么关系
3 楼
IvanLi
2007-01-22
这两个方法是使用junit分别测试的,使用的不是同一个stmt
2 楼
dengyin2000
2007-01-22
PreparedStatement预编译应该是在数据库server端吧。是不是要close Statement 和 PreparedStatement来测试。因为如果都是使用同一个stmt的话, 就没有考虑到编译的效率了。
1 楼
deafwolf
2007-01-22
PreparedStatement的目的主要是批处理,跟Statement比顺序执行的效率本来就是不合理的测试方式
发表评论
-
use hibernate3-maven to export sql based on entity
2011-08-07 18:19 1424<plugin> <group ... -
uninstall mysql completely in my Mac X 10.6
2011-08-07 12:19 1263sudo rm /usr/local/mysql ... -
my vimrc
2011-05-14 11:02 1750copy from http://www.vi-improve ... -
使用HSQLDB来作EJB3 EntityBean到Unit Test要点
2010-01-20 17:17 2147add <property name=" ... -
user xrandr to change my desktop's resolution
2009-12-16 17:04 1708xrandr --newmode "1280x ... -
XSS的关键之列表
2009-10-11 17:20 1862//this field are used tp esc ... -
python查看方法帮助(from dive into python)
2009-09-30 11:31 2661def info(object, spanding=10, c ... -
selenium 测试ajax的关键
2009-01-20 18:26 42691: waitForCondition(contidtion, ... -
RichFaces 手记
2008-10-07 15:46 0安装,除了richfaces 下载包中的jar( " ... -
代码检查工具
2008-09-25 11:48 2592findBugs, PMD, CheckStyle find ... -
CI工具hudson
2008-09-24 17:04 3144CI工具除了hudson,还有很多,例如CruiseContr ... -
创建solaris package step by step
2008-09-24 11:27 1948原文地址:http://www.ibiblio.org/pub ... -
什么是SVR4?我们为什么要选择SVR4?
2008-09-23 14:13 5014http://www.lslnet.com/linux/f/d ... -
IPS 中的pkg command学习笔记
2008-09-22 17:18 1865pkg(1): 使用pkg(1)来创建一个镜像,安装,升级,管 ... -
On Board前的学习计划
2008-09-18 09:37 15501:在virtual box 上虚拟一个OpenSolaris ... -
YUI Grid CSS的优雅设计
2008-09-02 22:38 2854最近加入了一个GAE的项目cpedialog,该项目的前端布局 ... -
我很懒,但是懒人有懒办法
2008-08-18 17:06 1838今天要使用jackrabbit做个小东西,上apache一看, ... -
当XPath遇上NameSpace
2008-07-23 19:39 6583在jdk5.0中,已经包含了对Xpath的支持,可一通过下面的 ... -
ubuntu下安装ipmsg-飞鸽传书
2008-07-21 09:32 29051 先下载 源码 下载的是gnome2版本的源码 http ... -
sudo 执行时无密码(不安全)
2008-07-17 17:18 2237sudo visudo root ALL=(ALL) ...
相关推荐
Java 中 PreparedStatement 和 Statement 的区别 Java 中的 PreparedStatement 和 Statement 都是用于执行 SQL 语句的接口,但是它们之间存在一些关键的区别。 首先,从数据库执行 SQL 语句的角度来看,使用 ...
这种差异导致PreparedStatement对象执行速度更快,特别是在执行多次相同的SQL语句时。 其次,PreparedStatement对象可以避免SQL注入攻击。在 Statement 对象中,如果用户输入的数据包含恶意代码,例如 Drop 表名,...
jdbc中preparedStatement比Statement的好处
- **性能**:由于预编译,`PreparedStatement`通常比`Statement`更快,尤其是在大量重复执行相同SQL时。 - **安全性**:`PreparedStatement`通过占位符防止SQL注入,而`Statement`则容易受到这类攻击。 - **...
Java面试题34.jdbc中preparedStatement比Statement的好处.mp4
一种可能的方法是通过日志配置,例如,启用MySQL的`Statement`和`PreparedStatement`日志,这样在执行时会打印出详细的SQL语句。 另外,开发工具如IntelliJ IDEA、Eclipse等,或者数据库管理工具如MySQL Workbench...
### PreparedStatement的详细...综上所述,无论从性能、安全性还是数据库无关性的角度,`PreparedStatement`都是比`Statement`更为优秀的选择,因此,在实际开发中,应尽可能地采用`PreparedStatement`来执行SQL语句。
#### 何时使用 Statement? - 当SQL语句简单,不会重复执行时。 - 对于读取数据的操作,如果数据量不大,可以考虑使用`Statement`。 - 当不需要参数化SQL语句时,例如只读操作。 #### 何时使用 PreparedStatement...
`PreparedStatement`是`Statement`接口的子接口,用于预编译SQL语句,并可以重复执行这些预编译过的SQL语句。这不仅能够提高应用程序的性能,还能提高安全性,因为它支持参数化查询,避免了SQL注入的风险。 #### 二...
首先,从创建时的区别开始,Statement 需要通过 Connection 对象的 createStatement() 方法创建,而 PreparedStatement 需要通过 Connection 对象的 prepareStatement() 方法创建,并且需要带有 SQL 语句。...
`PreparedStatement`的主要特点在于它可以预先编译SQL语句,并允许用户在执行前动态地设置SQL语句中的参数值,这使得它在执行相同或相似SQL语句时比普通的`Statement`更加高效。 #### 二、`PreparedStatement`与`...
NULL 博文链接:https://chaoyi.iteye.com/blog/2088080
在Java编程语言中,`PreparedStatement`是`java.sql`包中的一个接口,它继承自`Statement`类,并提供了预编译SQL语句的功能。预编译SQL语句的主要优势在于提高了执行效率和安全性。尤其在处理动态查询或频繁执行相同...
PreparedStatement对象的创建和预编译过程比Statement更为复杂和耗时。因此,在那些对性能要求极高且SQL语句几乎不重复执行的应用场景下,或许需要根据具体情况来权衡利弊。 总之,理解Statement和...
在Java编程中,PreparedStatement是Java SQL API中的一个接口,它是Statement接口的子接口。这个练习主要涉及如何使用PreparedStatement来插入宠物信息到数据库中。PreparedStatement的主要优势在于它的预编译能力和...
在Java的JDBC(Java Database Connectivity)中,与数据库交互的核心接口是Statement和PreparedStatement。这两个接口都是用于执行SQL语句的,但它们在特性和效率上有所不同。 Statement接口是最基本的SQL执行方式...
在实际开发中,为了提高效率和安全性,我们通常会使用PreparedStatement接口来代替Statement接口。 1. **PreparedStatement简介** PreparedStatement是Statement的一个子接口,它的主要优势在于预编译。预编译的...
### PreparedStatement 向数据库插入时间方法 #### 背景与问题描述 在Java应用程序中,我们经常需要将数据写入数据库。为了确保SQL查询的安全性和效率,通常会使用`PreparedStatement`来执行这样的操作。然而,在...
在数据库编程中,我们经常遇到两种执行SQL语句的方法:Statement和PreparedStatement。尽管Statement看起来更简洁,但在实际应用中,尤其是在使用ORM框架如MyBatis时,PreparedStatement成为了首选。那么,为什么...