【发布时间】:2010-10-15 19:28:33
【问题描述】:
所以我一直听说 PreparedStatements 对性能有好处。
我们有一个 Java 应用程序,在该应用程序中,我们使用常规的“语句”比使用“PreparedStatement”要多。在尝试使用更多 PreparedStatement 的同时,我试图更全面地了解 PreparedStatements 的工作原理——在客户端和服务器端。
那么如果我们有一些典型的 CRUD 操作并且在应用程序中重复更新一个对象,使用 PS 是否有帮助?我知道我们每次都必须关闭 PS,否则会导致游标泄漏。
那么它对性能有何帮助?驱动程序是否缓存预编译语句并在我下次执行 connection.prepareStatement 时给我一份副本?或者数据库服务器有帮助吗?
我理解有关 PreparedStatements 的安全优势的争论,我很欣赏下面强调这一点的答案。不过,我真的希望将讨论集中在 PreparedStatements 的性能优势上。
更新:当我说更新数据时,我的真正意思是更多地随机调用该方法多次。我理解下面提供的答案的优势,它要求在循环中重用语句。
// some code blah blah
update();
// some more code blah blah
update();
....
public void update () throws SQLException{
try{
PreparedStatement ps = connection.prepareStatement("some sql");
ps.setString(1, "foobar1");
ps.setString(2, "foobar2");
ps.execute();
}finally {
ps.close();
}
}
没有办法真正重用“ps”java 对象,我知道实际的 connection.prepareStatement 调用非常昂贵。
这让我回到了最初的问题。这个“一些 sql”PreparedStatement 是否仍然在我不知道的情况下被缓存和重用?
我还应该提到我们支持多个数据库。
提前致谢。
【问题讨论】:
-
如果你没有使用 PrepardStatements 并且不担心 SQL 注入攻击,那么你对 SQL 注入攻击的了解还不够。
-
不仅是 sql 注入,还减少了将类型作为字符串传递、转义特殊字符等的错误。另外,在使用完 PS 后关闭 PS,就像其他所有操作一样,这通常是在“批次”更新结束时。游标泄漏通常是由于打开 ResultSet 造成的。
-
+1 个好问题和几个好答案。对于 Oracle,预编译语句的巨大“性能”优势来自于数据库服务器,而不是单个语句的执行,而是相同 SQL 文本的重复执行。单次执行新语句不会有任何性能提升。当第二次、第三次执行该语句时,就会节省 CPU 周期。 Oracle 跳过了“硬解析”的所有繁重工作,并重用了之前准备好的查询计划。
-
哎呀,5年后,感觉这里仍然没有一个好的答案。特别是,我认为回答关于在使用不同的连接反复准备相同的查询时是否获得任何性能优势的部分是关键。我将悬赏赏金,以获得对此问题的良好、深入的回答。
-
你在问题中说:“没有办法真正重用'ps'java对象”。为什么不?这正是您实现性能提升的方式。
标签: java database performance prepared-statement