MySQL 缓存准备好的语句以提高性能

MySQL cached prepared statements for performance

如果您调用 mysql_stmt_close,是否准备好的语句未被 MySQL 缓存?

我想MySQL缓存常用语句。问题是我不知道 MySQL 如何处理缓存语句的所有细节。

例如,挂在mysql_stmt指针上,不断绑定不同的参数并执行它会更好吗?

或者,这只会节省我的 C 内存分配,因为 MySQL 实际上会根据查询匹配(或其他)缓存语句,而这与我 mysql_stmt_preparemysql_stmt_prepare 的次数无关mysql_stmt_close 或我 mysql_connect 多少次?

如果你发出 prepared statement, MySQL prepares some things like parsing and executions plans, so when you later bind the actual parameters, it doesn't need to do this (again). The preparation usually requires only some ms. If that's relevant will depend on the total execution time of your query, and you can obviously only save time if you run it more than once (but you don't lose time either if you just run it once). That being said, using prepared statements even if you just run it once is a standard security measure.

准备好的语句存储在服务器上,需要(一点点)内存。当您关闭它时它会被释放并且之后不会被缓存。它也是特定于一个连接的,因此不同的连接将为同一个查询分配自己的内存。

您可以使多个准备好的语句保持活动状态。打开准备语句的总数实际上有一个上限(由 max_prepared_stmt_count 给出),但这取决于有多少用户在使用您的应用程序(以及他们分配的内存,这通常仍然是可忽略)与您的考虑相关。

保持长时间准备好的语句有一些实际意义,最重要的是当你失去连接时准备好的语句会丢失(无论是意外还是你故意关闭它)。这可能会使您的代码复杂化,也可能不会复杂化(例如,重新初始化有关连接丢失的语句)。它还会强制您保持连接打开,虽然 MySQL 通常不需要很多资源来保持休眠连接打开,但您可能希望也可能不希望这样做。此外,这基本上会阻止您使用连接池(除非它们支持),因为您不能在不丢失准备好的语句的情况下将连接返回给池(尽管这通常与 c 应用程序不太相关)。

这是标准 c mysql api 的行为(按照您的语法建议)。如果您使用替代工具,此行为当然会有所不同。例如,java driver (可选)在 .close 上缓存语句。但它基本上是通过简单地不实际关闭它(通过 api),并在内部处理诸如连接丢失时重新初始化之类的事情来实现的。这意味着这样的(应用程序端)缓存可以有一些用途,虽然我不知道 c 的替代方案,但实现它当然是可能的(并且不应该太复杂)(而且很可能有人已经这样做了).

最后一点,您可能正在寻找:在 MySQL 8 之前,有一个 query cache 来缓存特定 sql 查询的结果。如果您 运行 使用完全相同的代码(使用完全相同的参数)进行两次查询,并且如果没有对涉及的表进行更新(并且如果启用了缓存并且结果集不是太大),MySQL 将从该缓存中获取结果而无需重新执行查询。它仅与准备好的语句密切相关,并且对应用程序透明(您不需要更改任何内容),但可能与缓存上下文相关。