一次执行后关闭PreparedStatement –这是设计缺陷吗?

问题描述 投票:6回答:5

我调查了很多地方,并听到了很多可疑的说法,即使只是出于性能方面的考虑,从PreparedStatementStatement在任何地方都应该被优先使用;一路声称PreparedStatement应该只用于批处理语句,而别无其他。

但是,在我关注的(主要是在线的)讨论中似乎有一个盲点。让我提出一个具体的方案。


我们有一个带有数据库连接池的EDA设计的应用程序。事件来了,其中有些需要持久性,有些则不需要。有些是人为产生的(例如,每X分钟更新/重置某些内容)。某些事件会按顺序处理,但其他类型的事件(也需要持久性)可以(并且将)同时处理。

除了那些人为生成的事件之外,没有需要持久性的事件如何到达的结构。

此应用程序是在很早以前(大约2005年)设计的,并且支持多个DBMS。典型的事件处理程序(需要持久性的地方):

  • 从池获取连接
  • 准备sql语句
  • 执行准备好的语句
  • 处理结果集,如果适用,请关闭它
  • 关闭准备好的陈述
  • 准备不同的语句,如有必要,并以相同的方式处理
  • 返回到池的连接

如果事件需要批处理,则该语句仅准备一次,并使用addBatch / executeBatch方法。这是明显的性能优势,这些情况与该问题无关。


最近,我已经收到一种意见,即准备(解析)语句,执行一次然后关闭的整个想法本质上是对PreparedStatement的滥用,无论服务器还是客户端准备好了,其提供的性能收益为零。使用了该语句,并且典型的DBMS(Oracle,DB2,MSSQL,MySQL,Derby等)甚至不会将这样的语句提升为准备好的语句缓存(或者至少不会将其默认的JDBC驱动程序/数据源提升)。] >

而且,我不得不在MySQL的开发环境中测试某些方案,看来Connector / J使用情况分析器同意这一想法。对于所有非批处理的准备好的语句,调用close()打印:

PreparedStatement created, but used 1 or fewer times. It is more efficient to prepare statements once, and re-use them many times


由于前面概述了应用程序设计的选择,因此,PreparedStatement实例缓存可保存连接池中每个连接的任何事件使用的每个事件的每个SQL语句,听起来是一个糟糕的选择。

有人可以进一步详细说明吗? 逻辑“准备执行(一次)关闭”是否有缺陷

并从本质上讲不鼓励?

P.S。当为every

非批处理SQL语句在useUsageAdvisor=true实例上调用cachePrepStmts=true时,为Connector / J明确指定useServerPrepStmts=trueuseServerPrepStmts=false并使用close()PreparedStatement仍会导致效率警告。

我浏览了很多地方,并听到了很多可疑的主张,从到处都应该首选PreparedStatement而不是Statement,即使只是为了提高性能;全部...

java jdbc eda
5个回答
3
投票

逻辑“准备-执行[一次]关闭”是否有缺陷并且实质上不鼓励?


2
投票
正如其他人已经指出的那样,

最昂贵的部分是解析语句


1
投票
PreparedStatements是可取的,因为无论您是否以编程方式创建一个都需要一个;在内部,每次运行查询时,数据库都会创建一个数据库-以编程方式创建一个数据库只会为您提供处理。每次创建并丢弃PreparedStatement不会比使用Statement增加太多开销。

0
投票
PreparedStatement已创建,但是使用了1次或以下。一次准备语句,然后多次重复使用,效率更高。

0
投票
© www.soinside.com 2019 - 2024. All rights reserved.