11

我读到 MySQL 不支持服务器端查询计划缓存。因此,如果我想使用 PreparedStatements 来获得性能优势,我可以做的是在 JDBC Connection 中启用语句缓存。因此,根据文档,它将启用基于每个连接的准备好的语句的缓存。

与 MySQL 具有服务器端查询计划缓存相比,通过 JDBC 连接进行 PreparedStatement 缓存的性能增益是多少?那么如果在物理连接的缓存中确实找到了PreparedStatement,是否意味着当它到达mysql服务器时,mysql不会对其进行查询优化,而是可以直接执行呢?

在使用 MySQL 作为我的数据库时,我是否应该在 JDBC 连接级别使用语句缓存?我正在使用带有 Mysql JDBC 连接器的 Hikari 数据库连接池。

4

4 回答 4

10

是的,如果您知道自己在做什么,缓存就不会受到伤害。如果您按照应有的方式重用准备好的语句,则将客户端缓存与服务器端缓存结合起来会带来性能优势(很多人忘记了最重要的部分:D)。只需正确设置Connector/J 属性

cachePrepStmts=true&useServerPrepStmts=true

虽然我不是微型基准测试的忠实拥护者,但这里有一个支持我的陈述(蹩脚的双关语)。关于基准测试的有趣部分是它表明启用服务器端缓存实际上可能会在没有一些客户端缓存的情况下减慢速度,但是启用两层缓存以及正确重用准备好的语句,您实际上可能会得到很好的加速.

于 2014-02-12T06:26:55.453 回答
8

HikariCP的作者之一在这里。请参阅HikariCP wiki,了解如何正确配置 MySQL 以进行准备好的语句缓存。准备好的语句缓存可以显着加快 SQL。此外,如果将用户提供的输入连接到 SQL 普通语句中,它可以避免对代码的 SQL 注入攻击,否则这种攻击会成功。 切勿编写包含用户提供的输入的 SQL 字符串。 始终使用准备好的语句,并将用户提供的输入设置为替换值。

于 2014-02-13T09:37:01.370 回答
3

您可以设置两个属性:

  • useServerPrepStmts- 启用服务器端准备好的语句,因为默认情况下,准备好的语句是在客户端模拟的。
  • cachePrepStmts- 启用语句缓存机制

性能结果

对于客户端语句,通过启用该cachePrepStmts设置可以提高吞吐量,如下图所示:

客户端语句缓存

而且,对于服务器端语句,通过启用以下cachePrepStmts属性还可以提高吞吐量:

服务器端语句缓存

因此,语句缓存机制也适用于客户端和服务器端准备好的语句。

在 MySQL 8.0.22 和 8.0.18 上进行测试时,使用单语句和多语句事务,客户端预准备语句的性能优于服务器端预准备语句。

因此,以下配置选项似乎产生了最好的结果:

useServerPrepStmts=false
cachePrepStmts=true
prepStmtCacheSize=500
prepStmtCacheSqlLimit=1024

设置最后两个属性是为了增加缓存限制,因为默认值对于许多数据驱动的应用程序来说太低了。

于 2021-01-07T08:15:38.320 回答
2

与 MySQL 相比,其他品牌和型号的表服务器将通过 JDBC 准备语句为您提供更多的性能优势。例如,Oracle 可以重用执行计划。

但是您仍然应该在 JDBC 中使用准备好的语句。使用它们的原因有很多,包括绑定变量带来的注入阻力。

于 2014-02-12T02:02:03.167 回答