精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2004-06-10
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2004-06-10
仅仅是讨论PrepareStatement和Statement是没有意义的,与此相关是还有你调用的方式:是不是简单的把用Statement的地方替换为PrepareStatement就完了,是不是创建Statement时参数不合适,是不是没有使用批处理方式. 你用的驱动是什么,SQL服务器的参数是否调整了等等...
ps:我没有用过Oracle,但就MSSQL上的PrepareStatement和Statement的对比是有很大区别的. |
|
返回顶楼 | |
发表时间:2004-06-10
我是把用到PreparedStatement的地方改成了Statement,直接拼sql语句执行,在Oracle上比PreparedStatement要快许多,Oracle服务器的调整我没有做,ORACLE的JDBC驱动我用得是Oracel官方驱动,应该不是驱动的问题,还有就是使用得是Oracle9,在它的管理器查看,看到了那个PreparedStatement的查询执行了很长时间,好像是在做什么优化,我怀疑是不是优化过头了
![]() |
|
返回顶楼 | |
发表时间:2004-06-10
你这种做法是有严重性能问题的。
http://forum.iteye.com/viewtopic.php?t=159 至于PreparedStatement为什么慢,你得要从你的view里面找原因了。 |
|
返回顶楼 | |
发表时间: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会有如此大的差别? |
|
返回顶楼 | |
发表时间:2004-06-10
这个sql是不好,可是由于一些原因,日期型的字段只能用字符来代替,没有办法,你能写出更好更快的Sql,请赐教:)
我知道它们之间的差别,我是想知道为什么在这种情况下,Statement的执行效果会比PreparedStatement会更好,而PreparedStatement一查询就像死了一样?这是我想知道的,也是我主要问的 ![]() |
|
返回顶楼 | |
发表时间: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时,效率就提上去了). 上面可能有说错的地方请指正. |
|
返回顶楼 | |
发表时间:2004-06-10
下面是主要的代码:
引用 String cancelSql = "select GateWay_ID,Fee_Terminal_Id,UniformService_id,Cancel_Date,Cancel_By from CancelUser where Cancel_Date >=? and Cancel_Date <? and GateWay_ID=? and Fee_Terminal_Id>=?";
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。 真搞不清是什么原因了。 ![]() |
|
返回顶楼 | |
发表时间:2004-06-10
从代码看来,是没有什么可疑之处(贴码可以用code标签,这样会好看一点).
我说的是驱动实现的问题,不是是否用thin的问题,因为每一个驱动实现哪些接口(像Statement,PreparedStatement,Connection,ResultSet等)可能都不一样. 再想一下,如果不是主动地请求,oracle会出现什么优化计划呢(当然我对oracle并不很懂)?,如果是主动请求的话,是谁向谁请求呢?很明显: 客户(可能是程序员)向驱动发送请求,驱动进行一些处理,再向数据库发送请求. 我们排除客户与数据库的问题(如果是主动请求的话,再说我们没有显示发送请求这些东西),那只有驱动的问题了. 当然,我这是推测. 最好的办法,你可以问一下oracle的工程师. |
|
返回顶楼 | |
发表时间:2004-06-10
极端情况下会出现这种问题。由于Oracle可以对PreparedStatement进行执行优化,而对代入常量的Statement无法执行优化,通常PreparedStatement执行速度快,不会引起内存问题,但是在极端情况下,PrepredStatement的执行优化可能会消耗很长的时间,那么直接执行Statement反而会提高执行效率。
不过你可以试试看当你第一次执行完毕PreparedStatement之后,再次执行PrepredStatement的速度是否有飞速提升。 |
|
返回顶楼 | |