如果我关闭 PreparedStatement,数据库中的缓存会丢失吗?

Posted

技术标签:

【中文标题】如果我关闭 PreparedStatement,数据库中的缓存会丢失吗?【英文标题】:If I close the PreparedStatement, would the caching in the Database be lost? 【发布时间】:2019-06-14 12:29:48 【问题描述】:
PreparedStatment ps = null;
public void executeQueries()
    try
        ps = conn.prepareStatement(Query1);
        // Execute Query1 here and do the processing.           

        ps = conn.prepareStatement(Query2);
        // Execute Query2 here and do the processing.

        //... more queries
    catch()
    finally
        ps.close(); // At this point would the caching of queries in DB be lost?
    

在我的应用程序中,我经常调用方法executeQueries()

我的问题是,如果我关闭方法内 finally 块中的PreparedStatement(我经常使用),数据库系统会删除缓存吗?如果是,我可以为整个应用程序创建一个全局PreparedStatement,因为我的应用程序中有大量查询数据库的 JAVA CLASSES。

谢谢!

更新:问题已被标记为重复,但链接的线程根本没有回答我的问题。 AFAIK,数据库系统将执行的查询存储在缓存中。它还存储他们的执行计划。这就是PreparedStatementStatement 表现更好的地方。但是,我不太确定在关闭PreparedStatement 后是否会删除与查询相关的信息。

【问题讨论】:

为什么会这样? 阅读@dogbane 的回答,解决您的问题。 @TimBiegeleisen 请参考问题中的更新。 @Thilo 这不是一个完全不合理的问题。 = 无意暗示它是。我对任何表明发生这种情况的文档更感兴趣。 @TimBiegeleisen 我不能代表 mysql,但以 Oracle 为例,如果你准备一个语句,它会为它缓存一个编译的执行计划,这将在你的数据库连接中继续存在(这样另一个使用相同 SQL 语句的同一用户的连接将从中受益)。 【参考方案1】:

特别是关于 MySQL,根据

8.10.3 Caching of Prepared Statements and Stored Programs

服务器在每个会话的基础上为准备好的语句和存储的程序维护缓存。为一个会话缓存的语句不能被其他会话访问。当会话结束时,服务器会丢弃为其缓存的所有语句。

因此关闭 PreparedStatement 不会从缓存中删除语句,但关闭 Connection 可能会。

...除非应用程序使用连接池,在这种情况下关闭Connection 不一定会结束数据库会话;它可能会保持会话打开,并将连接返回到池。

还有一个问题是这些语句是否真的在服务器上准备好了。这由useServerPrepStmts 连接字符串属性控制。 IIRC,默认情况下,服务器端准备好的语句是启用的。

【讨论】:

这意味着我可以关闭 PreparedStatements 而不必担心应用程序的效率。你能告诉我,在每次查询执行之后或直接在 finally 块中(在给定示例中提到的方式),究竟将 close() 命令放在哪里?考虑到语句被频繁执行,什么更合适? 通常认为最好的做法是在 ResultSet 和 Statements 完成工作后立即关闭它们。从 Java 7 开始,我们可以使用“try with resources”块来确保项目被关闭。

以上是关于如果我关闭 PreparedStatement,数据库中的缓存会丢失吗?的主要内容,如果未能解决你的问题,请参考以下文章

即使 PreparedStatement 仅使用一次,ResultSet 关闭错误后也不允许操作

在准备另一个Statement之前是不是需要关闭PreparedStatement

在使用 JDBC 的 DAO 类中,哪一个是处理关闭 ResultSet、PreparedStatement 和 Connection 的 try-catch 的最佳方法?

何时关闭 JDBC 中的 Connection、Statement、PreparedStatement 和 ResultSet

PreparedStatement超过最大游标数

创建preparedstatement的多个实例