Chinaunix首页 | 论坛 | 博客
  • 博客访问: 17162
  • 博文数量: 22
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 240
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-18 10:33
文章分类
文章存档

2015年(22)

我的朋友

分类: Mysql/postgreSQL

2015-03-01 12:01:48

    对于某些语句客户端可能会在会话期间多次执行,服务器中的语句转换为内部结构和缓存的结构的执行过程中使用的。高速缓存使服务器能够达到事半功倍的效果,因为它避免了会话期间再次需要转换语句的开销。转换和缓存出现的这些语句:

  • 准备好的语句,这两个在SQL级处理(使用PREPARE语句),以及那些 使用二进制的客户机/服务器协议处理(使用mysql_stmt_prepare()C API 函数)。该max_prepared_stmt_count 系统变量控制语句服务器缓存总数(预处理语句的所有会话数的总和)。

  • 存储程序(存储过程和函数,触发器和事件)。在这种情况下,服务器转换和缓存整个程序主体,该stored_program_cache系统变量指示存储程序的大致数量每个会话的服务器缓存。

    服务器维护缓存的预处理语句和存储程序的每个会话的基础上。语句缓存为一个会话是不能访问其他会话,当一个会话结束时,服务器将放弃缓存的任何声明。

    当服务器使用缓存内部声明的结构,就必须注意使架构不会过期。元数据的变化可能发生在使用该语句的对象,从而导致不匹配当前对象的定义和作为内部语句结构表示的定义之间。元数据发生变化的DDL语句,如那些创建,删除修改,重命名或截断(truncate)表,或分析,优化,或维护表。表中内容的变化(例如,使用INSERT或UPDATE)不改变元数据,也没有SELECT语句。

    这是问题所在的说明,假设一个客户准备这个发言:
    PREPARE s1 FROM 'SELECT * FROM t1';

    使用SELECT*扩展的内部结构的列在表中的清单。如果表中的列集修改使用ALTER TABLE,准备好的语句变为过期。如果服务器没有检测到这种变化接下来的时间客户端执行S1,准备好的语句将返回不正确的结果。

    为了避免因元数据变化的准备语句中引用的表或视图的问题时,服务器检测到这些变化,并自动reprepares语句,然后执行它。也就是说,在服务器重新解析语句,并重建内部结构。重新分析也发生后,引用的表或视图从表中定义的缓存刷新,无论是隐含,以腾出空间给新的条目在缓存中,或明确因FLUSH TABLES

    同样,如果发生对所使用的存储的程序对象的改变,则服务器重新解析程序内受影响的语句(的MySQL5.6.6之前,服务器不检测的元数据的变化影响存储程序,因此这种变化可能会导致不正确的结果或错误)。

    该服务器还检测为表达对象的元数据的变化。这可能会在特定的存储方案,例如DECLARE CURSOR或流控制语句如IF,CASE和RETURN语句中使用。

    为了避免重新分析整个存储程序,服务器重新解析只需要在程序中受影响的语句或表达式。例如:
  • 假设元数据表或视图改变。重新解析发生在一个SELECT*访问的表或视图的程序中,而不是在不访问表或视图的SELECT*。

  • 当一个语句受到影响,如果可能的话服务器只是重新解析它的部分。考虑这个CASE语句:
    CASE case_expr 
      WHEN when_expr1... 
      WHEN when_expr2...
      WHEN when_expr3... 
      ...
    END CASE
        如果只有when_expr3受到元数据变化的影响,该表达式是重新解析。case_exprand其他WHEN表达式无法重新解析。

    重新解析使用默认的数据库和SQL模式是有效为原始转换为内部形式。

    服务器尝试重新分析最多三次。如果所有尝试都失败,就会发生错误。

    重新解析是自动的,但它出现的程度,会减少准备好的语句和存储程序的性能。对于预处理语句时,Com_stmt_reprepare状态变量的repreparations磁道数

阅读(258) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~