PreparedStatement 缓存 - 这是啥意思(它是如何工作的)

Posted

技术标签:

【中文标题】PreparedStatement 缓存 - 这是啥意思(它是如何工作的)【英文标题】:PreparedStatement caching - what does it mean (how does it work)PreparedStatement 缓存 - 这是什么意思(它是如何工作的) 【发布时间】:2012-08-21 21:14:51 【问题描述】:

例如,我使用 c3p0 和一些定义的“maxStatements”来进行preparedStatement 缓存。 这种缓存到底有什么作用?它缓存什么样的数据。在什么级别(数据库,应用程序,..)? 从例子中理解它会很好。例如我有一个查询

select * from sometable where somecolumn=?

现在我在未缓存的准备好的语句中发送它。 现在我正在发送它并且它被缓存了。 有什么区别。第一种情况和第二种情况发生了什么。第一种情况和第二种情况发送到数据库服务器的是什么?

谢谢。

【问题讨论】:

【参考方案1】:

如果没有缓存,每次您从 Connection 请求一个 PreparedStatement 时,您都会得到一个新的 PreparedStatement。使用缓存,如果您提供相同的 SQL 字符串,您将经常获得完全相同的 PreparedStatement 类型的 Java 对象。如果您为 PreparedStatement 提供相同的 SQL,即使使用不同的参数,数据库通常可以重用执行计划等信息,但前提是您继续使用相同的 PreparedStatement。缓存不需要您的应用保留该 PreparedStatement 引用本身,从而使这更容易。

【讨论】:

【参考方案2】:

John Watts 的回答非常好。

请注意,由于语句缓存是透明的,因此无法提供示例代码:使用它的代码看起来与不使用它的代码完全一样。您只需在 c3p0 中通过将 maxStatements 和/或 maxStatementsPerConnection 设置为正值来打开语句缓存。

语句缓存带来的任何性能优势都取决于数据库/JDBC 驱动程序。要查看语句缓存是否有帮助,请先尝试在关闭语句缓存的情况下分析您的应用程序,然后将 maxStatementsPerConnection 设置为您的应用程序重复使用的准备语句查询的数量。对于某些应用程序/数据库/驱动程序,您会看到显着的好处。对于其他人,您不会看到任何物质利益。

【讨论】:

有什么经验法则吗?我的应用程序按顺序执行大约 100 个不同的 sql,因此我猜 PreparedStatement 池等于 50 命中率将为 0(LRU ?)。 最简单的做法是使用maxStatementsPerConnection 并将其设置为您的应用程序经常使用的PreparedStatements 的数量。 (即忽略应用程序初始化时使用的语句,或者很少用于管理目的等)如果您的应用程序总是按顺序执行 100 个不同的 PreparedStatements,那么,当然,尝试将 maxStatementsPerConnection 设置为 100,但存在风险这样做的内存和资源占用将超过任何好处,没有它你会过得更好。你必须看到。 @j23 有一条经验法则:永远不要在不稳定的数据库对象(表、视图、函数等)上使用语句缓存(即,更改表、删除列等),因为语句缓存将开始出现列类型不匹配、绑定值不匹配等问题。

以上是关于PreparedStatement 缓存 - 这是啥意思(它是如何工作的)的主要内容,如果未能解决你的问题,请参考以下文章

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

Oracle JDBC 优化:在 Spring 引导应用程序中启用 PreparedStatement 缓存

PreparedStatements 是不是由 CQL 字符串缓存? Datastax PreparedStatement 是不是保留语句 ID?

SQL攻击-预编译--缓存

Druid缓存

执行计划缓存,Prepared Statement性能跃升的秘密