对于客户端可能在会话期间多次执行的某些语句,服务器将该语句转换为内部结构,并缓存该结构以便在执行期间使用。缓存使服务器能够更有效地执行,因为它避免了在会话期间再次需要语句时重新转换语句的开销。对这些语句进行转换和缓存:
准备好语句,在SQL级别处理的语句(使用
准备
语句)和使用二进制客户机/服务器协议(使用mysql_stmt_prepare ()
C API函数)。的max_prepared_stmt_count.
系统变量控制服务器缓存的语句总数。(所有会议的准备陈述数量的总和。)存储程序(存储过程和函数、触发器和事件)。在这种情况下,服务器转换并缓存整个程序体。的
存储_program_cache.
系统变量表示每个会话中服务器缓存的存储程序的大约数量。
服务器在每个会话的基础上维护准备好的语句和存储的程序的缓存。为一个会话缓存的语句不能被其他会话访问。当会话结束时,服务器丢弃缓存的任何语句。
当服务器使用缓存的内部语句结构时,必须注意结构不会过时。语句使用的对象可能会发生元数据更改,导致当前对象定义与内部语句结构中表示的定义之间的不匹配。元数据发生更改为DDL语句,例如创建,删除,更改,重命名或截断表或分析,优化或修复表的那些。表内容更改(例如,具有插入
或更新
)不会更改元数据,也不会选择
陈述。
这是对这个问题的说明。假设客户端准备以下语句:
PREPARE s1 FROM 'SELECT * FROM t1';
的选择 *
将内部结构展开到表中列列表中。如果要修改表中的列表集ALTER TABLE
,准备好的声明过期了。如果服务器未在下次执行时检测到此更改s1
,则预处理语句返回不正确的结果。
为避免由Metadata导致的问题更改为所需语句引用的表或视图,服务器会检测到这些更改,并在下次执行时自动重新重新重复语句。也就是说,服务器缩回了语句并重建内部结构。在引用的表或视图中从表定义缓存中刷新后,也会发生归库,无论是隐含的方式,都可以为缓存中的新条目腾出空间,或者显式冲洗表
.
类似地,如果存储程序使用的对象发生更改,则服务器在程序中拒绝受影响的语句。
服务器还检测表达式中对象的元数据更改。这些可以在特定于存储程序的语句中使用,例如宣布游标
或流量控制陈述,如如果
,案件
, 和返回
.
为避免归库整个存储的程序,因此服务器仅根据需要在程序中缩减受影响的语句或表达式。例子:
假设表或视图的元数据发生了更改。重新解析发生在
选择 *
在访问表或视图的程序中,但不是为选择 *
它不访问表或视图。当一条语句受到影响时,如果可能的话,服务器只对其进行部分解析。考虑一下这个
案件
陈述:案件case_expr什么时候什么时候_EXPR1.... 什么时候什么时候_EXPR2.... 什么时候什么时候_EXPR3.......结束案例
元数据变更仅影响
什么时候
,这个表达式被解析。什么时候_EXPR3.
case_expr
和另一个什么时候
表达式没有被解析。
归库使用默认数据库和SQL模式生效,以便原始转换为内部表单。
服务器尝试重新解析多达三次。如果所有尝试都失败,就会出现错误。
归库是自动的,但在它发生的程度上,减少准备的语句和存储的程序性能。
对于预处理语句,Com_stmt_reprepare
状态变量跟踪重载的数量。