Java 准备好的报表和业绩

Java 准备好的报表和业绩,java,database,performance,prepared-statement,Java,Database,Performance,Prepared Statement,所以我一直听说准备好的报表有利于业绩 我们有一个Java应用程序,其中我们使用常规的“语句”多于使用“PreparedStatement”。在尝试使用更多PreparedStatements的同时,我试图更彻底地了解PreparedStatements是如何在客户端和服务器端工作的 因此,如果我们有一些典型的CRUD操作,并在应用程序中重复更新对象,那么使用PS有帮助吗?我知道我们每次都必须关闭PS,否则会导致光标泄漏 那么它对性能有什么帮助呢?驱动程序是否缓存预编译语句,并在下次执行conne

所以我一直听说准备好的报表有利于业绩

我们有一个Java应用程序,其中我们使用常规的“语句”多于使用“PreparedStatement”。在尝试使用更多PreparedStatements的同时,我试图更彻底地了解PreparedStatements是如何在客户端和服务器端工作的

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

那么它对性能有什么帮助呢?驱动程序是否缓存预编译语句,并在下次执行connection.prepareStatement时给我一个副本?或者DB服务器有帮助吗

我理解关于准备好的声明的安全好处的论点,我赞赏下面强调这一点的答案。然而,我真的想把讨论的重点放在预处理报表的性能优势上

更新:当我说更新数据时,我的意思是更多的方法被随机调用多次。我理解下面提供的答案的优点,它要求在循环中重复使用语句

    // 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调用非常昂贵

这让我回到了最初的问题。这个“somesql”PreparedStatement是否仍在我不知道的封面下被缓存和重用

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


提前感谢。

准备好的语句在第一次使用后确实会被缓存,这是它们在性能上优于标准语句的地方。如果你的陈述没有改变,那么建议使用这种方法。它们通常存储在语句缓存中,供alter使用

更多信息可在此处找到:

您可能希望将SpringJDBCTemplate作为直接使用JDBC的替代方案


重新使用您准备的语句时,准备好的语句可以提高性能:

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注入。在我的公司,这是一个面试问题;如果弄错了,我们可能不会雇佣你。

有趣的是:几年前,我在Java 1.4中使用ODBC对准备好的语句和动态语句进行了一些实验,使用Oracle和SQL Server后端。我发现,对于某些查询,准备好的语句可以快20%,但对于哪些查询改进到什么程度,存在供应商特定的差异。(事实上,这并不奇怪。)

底线是,如果重复使用同一个查询,准备好的语句可能有助于提高性能;但是如果你的表现很差,你需要立即采取措施,不要指望用事先准备好的陈述来给你带来彻底的提升。(20%通常没什么好写的。)


当然,你的里程数可能会有所不同。

事先准备好的陈述主要是关于性能的,这是一种误解,尽管这是一种很常见的误解


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


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

解析SQL并不是唯一的事情。需要验证表和列是否确实存在,创建查询计划等。您可以使用PreparedStatement支付一次

实际上,绑定以防止SQL注入是一件非常好的事情。这还不够,IMO。在进入持久层之前,您仍然应该验证输入。

这就是让我回到原始问题的原因。这个“somesql”PreparedStatement是否仍在我不知道的封面下被缓存和重用

是的,至少在甲骨文方面是这样。根据《Oracle®数据库JDBC开发人员指南》(增加了重点)

启用隐式语句缓存时,当调用此语句对象的
close
方法时,JDBC会自动缓存准备好的或可调用的语句。准备好的和可调用的语句使用标准连接对象和语句对象方法进行缓存和检索

普通语句不会隐式缓存,因为隐式语句缓存使用SQL字符串作为键,而创建普通语句时不使用SQL字符串。因此,隐式语句缓存仅适用于使用SQL字符串创建的
OraclePreparedStatement
OracleCallableStatement
对象。不能对OracleStatement使用隐式语句缓存。创建
OraclePreparedStatement
OracleCallableStatement
时,JDBC驱动程序会自动在缓存中搜索匹配的语句


与常规语句相比,准备好的语句在性能方面有一些优势,这取决于您如何使用它们。如前所述,如果需要多次执行同一查询