准备语句和性能

所以我一直听说ReadyStatements对性能有好处。

我们有一个Java应用程序,其中我们使用常规的“语句”比使用“准备语句”的次数多。在尝试使用更多PredentStatements的同时,我试图更全面地了解ReadyStatements的工作原理 - 在客户端和服务器端。

因此,如果我们有一些典型的CRUD操作并在应用程序中重复更新对象,那么使用PS是否有帮助?我知道我们每次都必须关闭PS,否则会导致游标泄漏。

那么,它如何帮助提高性能呢?驱动程序是否缓存预编译的语句,并在下次执行 connection.prepareStatement 时为我提供一份副本?或者数据库服务器是否有帮助?

我理解关于ReadyStatements安全优势的论点,我很欣赏下面强调它的答案。但是,我真的想让这次讨论的重点放在ReadyStatements的性能优势上。

更新:当我说更新数据时,我真的意味着这种方法被随机调用几次。我理解下面提供的答案中的优势,它要求在循环中重用语句。

    // 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”的PrekedStatement是否仍在我不知道的掩护下被缓存和重用?

我还应该提到,我们支持几个数据库。

提前致谢。


答案 1

预先准备的陈述主要是关于性能的想法是一种误解,尽管这是一个非常普遍的误解。

另一张海报提到,他注意到Oracle和SQL Server的速度提高了约20%。我注意到MySQL也有类似的数字。事实证明,解析查询并不是所涉及的工作的重要组成部分。在非常繁忙的数据库系统上,也不清楚查询分析是否会影响整体吞吐量:总体而言,它可能只会耗尽 CPU 时间,否则当数据从磁盘返回时,CPU 时间将处于空闲状态。

因此,作为使用预准备语句的原因,对 SQL 注入攻击的保护远远超过了性能改进。如果您不担心SQL注入攻击,则可能应该...


答案 2

预准备语句在重复使用您准备的同一语句时可以提高性能:

PreparedStatement ps = connection.prepare("SOME SQL");

for (Data data : dataList) {
  ps.setInt(1, data.getId());
  ps.setString(2, data.getValue();
  ps.executeUpdate();
}

ps.close();

这比在循环中创建语句快得多。

某些平台还缓存预准备语句,以便即使关闭它们也可以更快地重建它们。

但是,即使性能相同,您仍应使用预准备语句来防止 SQL 注入。在我的公司,这是一个面试问题;弄错了,我们可能不会雇用你。


推荐