首页 存档 技术 查看内容

Mysql查询缓存研究

2018-3-30 13:00 |来自: 互联网 277 0

摘要: 转载声明:本文为DBA 社群原创文章,转载必须连同本订阅号二维码全文转载,并注明作者名字及来源:DBA 社群(dbaplus)。 专家简介 李季鹏 【DBA 社群开源数据库用户组】联合发起人 5年 MySQL经验,主导运营商去IO ...



转载声明:本文为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%'查看




与缓存相关的命令如下:

  • FLUSH QUERY CACHE。用于清理查询缓存碎片以提高内存使用性能。该语句不从缓存中移出任何查询。

  • RESET QUERY CACHE。用于清空查询缓存所有内容。


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

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部