我调查了很多地方,并听到了很多可疑的说法,即使只是出于性能方面的考虑,从PreparedStatement
到Statement
在任何地方都应该被优先使用;一路声称PreparedStatement
应该只用于批处理语句,而别无其他。
但是,在我关注的(主要是在线的)讨论中似乎有一个盲点。让我提出一个具体的方案。
我们有一个带有数据库连接池的EDA设计的应用程序。事件来了,其中有些需要持久性,有些则不需要。有些是人为产生的(例如,每X分钟更新/重置某些内容)。某些事件会按顺序处理,但其他类型的事件(也需要持久性)可以(并且将)同时处理。
除了那些人为生成的事件之外,没有需要持久性的事件如何到达的结构。
此应用程序是在很早以前(大约2005年)设计的,并且支持多个DBMS。典型的事件处理程序(需要持久性的地方):
如果事件需要批处理,则该语句仅准备一次,并使用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=true
和useServerPrepStmts=false
并使用close()
或PreparedStatement
仍会导致效率警告。我浏览了很多地方,并听到了很多可疑的主张,从到处都应该首选PreparedStatement而不是Statement,即使只是为了提高性能;全部...
逻辑“准备-执行[一次]关闭”是否有缺陷并且实质上不鼓励?
最昂贵的部分是解析语句
PreparedStatements
是可取的,因为无论您是否以编程方式创建一个都需要一个;在内部,每次运行查询时,数据库都会创建一个数据库-以编程方式创建一个数据库只会为您提供处理。每次创建并丢弃PreparedStatement
不会比使用Statement
增加太多开销。PreparedStatement已创建,但是使用了1次或以下。一次准备语句,然后多次重复使用,效率更高。