精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2004-06-10
没有提高,第一次要20分,第二次将近17分钟:(
|
|
返回顶楼 | |
发表时间:2004-06-10
agilejava
单次运行PreparedStatement虽然要比Statement要慢一些,但是绝对不可能出现数量级的差异。 这是一篇蛮早的关于Oracle的JDBC性能测试文章,里面对比了thin和oci,PreparedStatment和Statment的差异,但是也没有像你这种情况差别巨大。 http://www.onjava.com/lpt/a/1480 是否你有什么设置的地方不正确? |
|
返回顶楼 | |
发表时间:2004-06-11
to Quake Wang:
我对Oracle不熟悉,是同事建好视图我查询就可以了,谁想有这么严重的问题:( ,你说的设置是指哪方面的,我问过同事,他们也没有给出我好的建议,用不用我把建视图的sql弄到这来了,可是用Statement查询时速度是挺快的啊,如果是视图的问题这方面有些怀疑。我先看看你给的那个文章,看看能不能发现解决办法。谢谢!:) |
|
返回顶楼 | |
发表时间:2004-06-11
来源:Java Programming with Oracle JDBC
http://www.oreilly.com/catalog/jorajdbc/chapter/ch19.html 里面有详细的图表说明为什么Statement比PreparedStatement快。 摘录一段如下: There's a popular belief that using a PreparedStatement object is faster than using a Statement object. After all, a prepared statement has to verify its metadata against the database only once, while a statement has to do it every time. So how could it be any other way? Well, the truth of the matter is that it takes about 65 iterations of a prepared statement before its total time for execution catches up with a statement. 翻译过来就大概是说: 大家普遍误解PreparedStatment对象要比Statement对象效率高。毕竟,一个prepared statement只要校验一次,而一个普通statement每次都要校验。既然如此,在什么情况下后者会比前者效率高呢?事实是一个prepared statement要执行65次以上才能赶上一个普通statement的执行效率。 详细的内容大家自己看上面的连接吧。 |
|
返回顶楼 | |
发表时间:2004-06-11
确实是好文,首先它纠正了PreparedStatement的效率一定会比Statement高这一看法,但是按照它的比较结果,和我这里的比较结果就差太多了。Statement查询就10秒,而PreparedStatement的查询时间刚才又测了一下,要30多分钟,搞死我了快
|
|
返回顶楼 | |
发表时间:2004-06-14
其实PreparedStatement与statement性能差异是与数据库相关的
就应用来说,个人认为性能的差距微乎其微,一条糟糕的sql产生的损耗 远大于使用PreparedStatement或者statement带来的收益 除了性能之外,Statement可能会给你的oracle带来重编译过多的烦恼 严重点导致oracle崩溃,我们的项目中曾经出现过这样的情况。 至于一楼楼主的问题我怀疑是拿不同类型放在等式两边的原因 (类似where 数字类型=字符类型),请将全部java代码 建表语句,贴出。 例如: select * from dcustmsg where phone_no='100001' (这里的phone_no是numeric型) #如下,摘自oracle的电子杂志: 执行许多SQL语句的JDBC程序产生大量的Statement和PreparedStatement对象。通常认为PreparedStatement对象比Statement对象更有效,特别是如果带有不同参数的同一SQL语句被多次执行的时候。PreparedStatement对象允许数据库预编译SQL语句,这样在随后的运行中可以节省时间并增加代码的可读性。 然而,在Oracle环境中,开发人员实际上有更大的灵活性。当使用Statement或PreparedStatement对象时,Oracle数据库会缓存SQL语句以便以后使用。在一些情况下,由于驱动器自身需要额外的处理和在Java应用程序和Oracle服务器间增加的网络活动,执行PreparedStatement对象实际上会花更长的时间。 然而,除了缓冲的问题之外,至少还有一个更好的原因使我们在企业应用程序中更喜欢使用PreparedStatement对象,那就是安全性。传递给PreparedStatement对象的参数可以被强制进行类型转换,使开发人员可以确保在插入或查询数据时与底层的数据库格式匹配。 当处理公共Web站点上的用户传来的数据的时候,安全性的问题就变得极为重要。传递给PreparedStatement的字符串参数会自动被驱动器忽略。最简单的情况下,这就意味着当你的程序试着将字符串“D'Angelo”插入到VARCHAR2中时,该语句将不会识别第一个“,”,从而导致悲惨的失败。几乎很少有必要创建你自己的字符串忽略代码。 在Web环境中,有恶意的用户会利用那些设计不完善的、不能正确处理字符串的应用程序。特别是在公共Web站点上,在没有首先通过PreparedStatement对象处理的情况下,所有的用户输入都不应该传递给SQL语句。此外,在用户有机会修改SQL语句的地方,如HTML的隐藏区域或一个查询字符串上,SQL语句都不应该被显示出来。 |
|
返回顶楼 | |
发表时间:2004-06-15
下面是建立View的语句:
CREATE OR REPLACE VIEW CANCELUSER ( GATEWAY_ID, FEE_TERMINAL_ID, UNIFORMSERVICE_ID, REGISTER_DATE, CANCEL_DATE, CREATE_BY, CANCEL_BY ); AS select century.anonymous_cancel_user.GATEID as GateWay_ID, century.anonymous_cancel_user.USERPHONENUM as Fee_Terminal_Id, 13 as UniformService_id, to_char(century.anonymous_cancel_user.LASTCUSTDATE , 'yyyy-mm-dd hh24:mi:ss'); as Register_Date, to_char(century.anonymous_cancel_user.CREATEDATE, 'yyyy-mm-dd hh24:mi:ss'); as Cancel_Date, century.anonymous_cancel_user.CREATEBY as Create_By, century.anonymous_cancel_user.UPDATEBY as Cancel_By from century.anonymous_cancel_user where sysdate - createdate < 85 下面是我的测试程序: String cancelSql = "select GateWay_ID,Fee_Terminal_Id,UniformService_id,Cancel_Date,Cancel_By from CancelUser where GateWay_ID=? and Cancel_Date >=? and Cancel_Date <? and Fee_Terminal_Id>=?"; Connection conn = null; try { conn = DBUtil.getConnection(config);; PreparedStatement cancelStatement = conn.prepareStatement(cancelSql);; cancelStatement.setInt(1, 10);; cancelStatement.setString(2, "2004-06-06 10:10:10");; cancelStatement.setString(3, "2004-06-08 10:10:10");; cancelStatement.setString(4, "1350000000");; UtilLog.debug("begin:", "test");; ResultSet cancelResult = cancelStatement.executeQuery();; while (cancelResult.next();); { System.out.println("fee_terminal_id:" + cancelResult.getString(1); + "test");; } UtilLog.debug("end:", "test");; } catch (Exception e); { e.printStackTrace();; } finally { if (conn != null); { DBUtil.closeConnection(conn);; } } 两个附件是用两种方法查询时的执行计划,希望对你的分析有帮助:) 再次感谢:) |
|
返回顶楼 | |
发表时间:2004-06-15
经过网友的帮助,终于解决了这个问题,原因在于fee_terminal_id建立了索引,而oracle在执行查询时按照这个索引先找到所有的行,之后再查询这些记录,而符合fee_terminal_id的记录有100多万,导致了查询速度非常之慢,在我把这个索引删除之后查询速度在8-9秒之间,很快。因此索引有时会起到相反的作用,要小心使用:)
非常感谢大家的帮助,特别要感谢卜志明,是他的帮助和指导帮助我找到了问题。:) |
|
返回顶楼 | |
发表时间:2004-06-16
很多情况下我是这样子的:
外层函数 call 内层函数 那个PreparedStatement是在内层里创建的,所以每调用一次内层函数都要重建一个PreparedStatement,这样内层的PreparedStatement创建起来只用了一次就被弃掉了,这样是不是不能起到Prepare的作用呢?还是只要是用Prepare过的,它会在服务器上缓存的。 |
|
返回顶楼 | |
发表时间:2004-06-16
这得视数据库的不同而定
|
|
返回顶楼 | |