转载声明:本文为DBA 社群原创文章,转载必须连同本订阅号二维码全文转载,并注明作者名字及来源:DBA 社群(dbaplus)。 专家简介
【DBA 社群开源数据库用户组】联合发起人 5年 MySQL经验,主导运营商去IOE技术落地,精通MySQL数据库及相关解决方案,对MySQL集群架构,高可用方案有深入的研究。 MySQL的查询缓存并非缓存执行计划,而是查询及其结果集,这就意味着只有相同的查询操作才能命中缓存,因此MySQL的查询缓存命中率很低,另一方面,对于大结果集的查询,其查询结果可以从cache中直接读取,有效的提升了查询效率。 1 1.1 工作流程 A):服务器接收SQL,以SQL DB Query_cache_query_flags作为hash查找键; B):找到了相关的结果集就将其返回给客户端; C):如果没有找到缓存则执行权限验证、SQL解析、SQL优化等一些列的操作; D):执行完SQL之后,将结果集保存到缓存 1.2 相关参数及命令 与缓存相关的主要参数如下表所示。可以使用命令SHOW VARIABLES LIKE '%query_cache%'查看 与缓存相关的状态变量如下表所示。可以使用命令SHOW STATUS LIKE '%Qcache%'查看 与缓存相关的命令如下:
2 2.1 在查询缓存中查找结果当服务器端接收到查询包后,系统就会检查查询缓存中是否有该查询,因此利用查询缓存可以省去SQL解析和处理操作,该步骤被封装在query_cache_send_result_to_client()函数,位于sql/sql_parse.cc 的mysql_parse()函数中,而query_cache_send_result_to_client()函数则宏定义于sql/sql_cache.h,详细过程则在sql/sql_cache.cc的send_result_to_client()函数中。 MySQL使用SQL DB Query_cache_query_flags作为hash查找键,从缓存中查找SQL的结果集,而SQL语句的这一部分会先去掉首尾的空格,所以首尾有无空格不会被认为是不同的SQL,该过程也在send_result_to_client()函数中。 2.2何时插入查询缓存MySQL得到结果集后,将结果集以包的形式发送到客户端,在将包发送到客户端之前会将包保存到查询缓存中。是否将结果集插入到查询缓存取决于查询SQL,能够插入到查询缓存的对象如前所述。 该过程封装在query_cache_insert ()函数中,该函数位于sql/sql_cache.cc中 2.3查找空闲块查询缓存初始化时,整个查询缓存被视为1个空闲块。当有新的查询需要缓存时,就需要分配一个新的缓存块。MySQL会尝试从所有空闲块中找出最适合大小的内存块(即大于所需块大小的最小缓存块)分配给新的查询。如果没找到这种块,则查找小于所需块大小的最大缓存块。如果没有空闲块,就将最老的查询移出缓存,而后再次分配内存,重复之前的步骤,直到找出合适的块。 2.4空闲块分割与合并如果找到了合适大小的缓存块,并且该块大于所需大小,则将它分割为两个缓存块。新块不能小于min_allocation_unit_bytes。每当产生一个空闲块,系统会检查其临近块中是否包含空闲块,如果包含则将它们合并为一个空闲块。 2.5空闲块存储根据空闲块的大小,将其存储到不同的区域中,各区域按照存储块的大小以降序排列,每个空闲块按照大小成近似对数分布。 空闲块存储步骤如下所述,query_cache_size为用户设定的查询缓存大小。 区域1:第一个区域中存储的空闲块大小为size |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|