论坛首页 Java企业应用论坛

PreparedStatement一定会提高性能吗?

浏览 31862 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-06-10  
PreparedStatement是一个“预编译”的Statement,按理说用它全执行sql 查询应该不会很慢才对,可是正是它花了我一天的时间才发现性能在瓶颈原因。最近在做一个小系统,使用PreparedStatement来从N个数据库的视图中查询数据,有SQL SERVER和ORACLE两种数据库,在SQL SERVER上查询数据库时没有问题,速度还可以,但是用相同的PreparedStatement在Oracel上查询视图时,10几分钟后还没有响应,有一个视图根本就没有查出结果来。后来经同事提醒,改为Statement来试,很快就有了查询结果,这是为什么啊?难道PreparedStatement会降低查询速度吗?谢谢!
   发表时间:2004-06-10  
仅仅是讨论PrepareStatement和Statement是没有意义的,与此相关是还有你调用的方式:是不是简单的把用Statement的地方替换为PrepareStatement就完了,是不是创建Statement时参数不合适,是不是没有使用批处理方式. 你用的驱动是什么,SQL服务器的参数是否调整了等等...

ps:我没有用过Oracle,但就MSSQL上的PrepareStatement和Statement的对比是有很大区别的.
0 请登录后投票
   发表时间:2004-06-10  
我是把用到PreparedStatement的地方改成了Statement,直接拼sql语句执行,在Oracle上比PreparedStatement要快许多,Oracle服务器的调整我没有做,ORACLE的JDBC驱动我用得是Oracel官方驱动,应该不是驱动的问题,还有就是使用得是Oracle9,在它的管理器查看,看到了那个PreparedStatement的查询执行了很长时间,好像是在做什么优化,我怀疑是不是优化过头了
0 请登录后投票
   发表时间:2004-06-10  
你这种做法是有严重性能问题的。

http://forum.iteye.com/viewtopic.php?t=159

至于PreparedStatement为什么慢,你得要从你的view里面找原因了。
0 请登录后投票
   发表时间:2004-06-10  
robbin大哥,谢谢你的帖子,你推荐的帖子我看了,我再详细描述一下我的问题:)
那个视图,应该有100多万的记录,我先用PreparedStatement来查询,结果就是上面我说的,很慢,以至于根本查不出结果来。当我用Staement查询时,最多10几秒也就查出来了,如果视图有问题,那么Statement查询时也应该是比较慢或查不出结果来。sql语句是像下面这样的:
引用
select GateWay_ID,Fee_Terminal_Id,UniformService_id,Register_Date,Create_By from FeeUser where Register_Date >= '2004-06-08 16:13:35' and Register_Date< '2004-06-08 16:15:00' and GateWay_ID=10 and Fee_Terminal_Id>='13500000000'


我想知道为什么PreparedStaement和Statement会有如此大的差别?
0 请登录后投票
   发表时间:2004-06-10  
这个sql是不好,可是由于一些原因,日期型的字段只能用字符来代替,没有办法,你能写出更好更快的Sql,请赐教:)

我知道它们之间的差别,我是想知道为什么在这种情况下,Statement的执行效果会比PreparedStatement会更好,而PreparedStatement一查询就像死了一样?这是我想知道的,也是我主要问的
0 请登录后投票
   发表时间:2004-06-10  
从现象来看,与PreparedStatement没有多大关系(楼主说在SQLSERVER没有什么问题,在oracle就有问题),只能说跟你的驱动有问题(因为每一个驱动实现PreparedStatement都不一样,这个可能性很大).
还有,希望楼主把调用数据库的代码也能贴一下.

当都只是执行一次的话,PreparedStatement与Statement之间的差别并不大,但如果你是多次进行SQL操作,那PreparedStatement的效率就要比Statement好.例如:

PreparedStatement:

...
st=con.prepareStatment("INSERT INTO 表 (字段1,字段2); VALUES(?,?);");;
for(int pos=0;pos<值s.length;pos++);{
	st.setXXX(1,值s[pos);;
	st.setXXX(2,值s[pos]);;
	st.executeUpdate;
}
...

Statement:

...
for(int pos=0;pos<值s.length;pos++);{
	st.executeUpdate("INSERT INTO 表 (字段1,字段2); VALUES(" + 值s[pos] + "," + 值s[pos] + ");");;
}
...


不过这也与你的JDBC驱动的实现有关,还有就是与你的SQL有关,
例如:
SELECT count(*); FROM 表 ORDER BY 字段


这个SQL在SQLSERVER 2000就不能执行,但在ORACLE 8.1.6 就可以.
但这个可以:

SELECT count(*); FROM 表 ORDER BY 常量


还有就是一些数据库本身的特性,例如:SQL SERVER 2000的索引的方法与ORACLE就不一样,所以就算是大家都一样的索引可能效率有很大的区别(不过看来楼主的问题与这个无关,因为用Statement时,效率就提上去了).

上面可能有说错的地方请指正.
0 请登录后投票
   发表时间:2004-06-10  
下面是主要的代码:
引用
String        cancelSql              = "select GateWay_ID,Fee_Terminal_Id,UniformService_id,Cancel_Date,Cancel_By from CancelUser where Cancel_Date  &gt;=? and Cancel_Date &lt;?  and GateWay_ID=? and Fee_Terminal_Id&gt;=?";

PreparedStatement cancelStatement =conn.prepareStatement(cancelSql);
cancelStatement.setString(1, this.dateFormat.format(startTime)); cancelStatement.setString(2, this.dateFormat.format(endTime)); cancelStatement.setInt(3,MOBILE_PUBLIC_GATE_WAY);
cancelStatement.setString(4, MOBILE_135);

ResultSet result = cancelStatement..executeQuery();

这个问题很奇怪,很感激大家的解答
可是问题到现在还是没有解决,我觉得可能不是jdbc驱动的问题,使用的是thin连接,而且在oracel的企业管理器里的会话中看到的是,这个sql已经开始执行了, 还有优化计划,一共分三步,具体什么我也记不清了,还有什么成本分析,一个查询是33,另一个查询是99。 真搞不清是什么原因了。
0 请登录后投票
   发表时间:2004-06-10  
从代码看来,是没有什么可疑之处(贴码可以用code标签,这样会好看一点).

我说的是驱动实现的问题,不是是否用thin的问题,因为每一个驱动实现哪些接口(像Statement,PreparedStatement,Connection,ResultSet等)可能都不一样.

再想一下,如果不是主动地请求,oracle会出现什么优化计划呢(当然我对oracle并不很懂)?,如果是主动请求的话,是谁向谁请求呢?很明显:
客户(可能是程序员)向驱动发送请求,驱动进行一些处理,再向数据库发送请求.
我们排除客户与数据库的问题(如果是主动请求的话,再说我们没有显示发送请求这些东西),那只有驱动的问题了.

当然,我这是推测.
最好的办法,你可以问一下oracle的工程师.
0 请登录后投票
   发表时间:2004-06-10  
极端情况下会出现这种问题。由于Oracle可以对PreparedStatement进行执行优化,而对代入常量的Statement无法执行优化,通常PreparedStatement执行速度快,不会引起内存问题,但是在极端情况下,PrepredStatement的执行优化可能会消耗很长的时间,那么直接执行Statement反而会提高执行效率。

不过你可以试试看当你第一次执行完毕PreparedStatement之后,再次执行PrepredStatement的速度是否有飞速提升。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics