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

时间:2018-07-28 00:26:28

标签: mysql c prepared-statement

如果调用mysql_stmt_close,MySQL是否不会缓存预备语句?

我希望MySQL缓存常用的语句。问题是我不了解MySQL如何处理缓存语句的所有细节。

例如,最好挂在mysql_stmt指针上并连续绑定不同的参数并执行它?

或者,那只会为我节省C内存分配,因为MySQL实际上基于查询匹配(或其他方式)缓存语句,而与我mysql_stmt_preparemysql_stmt_close的次数无关,或者我mysql_connect有多少次?

1 个答案:

答案 0 :(得分:2)

如果发出prepared statement,MySQL会准备一些诸如解析和执行计划之类的事情,因此当您以后绑定实际参数时,它不需要(再次)执行此操作。准备工作通常只需要几毫秒。如果相关,则取决于查询的总执行时间,并且显然,只有多次运行它,您才可以节省时间(但是,只要运行一次,也不会浪费时间)。话虽这么说,即使您只运行一次,也使用准备好的语句是standard security measure

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

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

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

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

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