ITPub博客

首页 > 数据库 > MySQL > MySQL Query Cache开启与否的必要性分析

MySQL Query Cache开启与否的必要性分析

原创 MySQL 作者:bestpaydata 时间:2016-03-28 18:09:17 0 删除 编辑

      众所周知,Mysql Query Cache能够存储select语句及其产生的数据结果,Mysql中的参数query_cache_type都能控制Query Cache的开启和关闭功能,实现mysql对于数据的缓存功能。对于innodb引擎的表来说,数据缓存于InnoDB Buffer Pool中,如图1,在下一次执行查询语句时,在Query Cache有可能会从InnoDB Buffer Pool里读取结果。
                                        
                                                                                            图1

MySQL中,Query Cache功能默认都是打开的,query_cache_type:控制 Query Cache 功能的开关,可以设置为0(OFF),1(ON)2(DEMAND)三种,意义分别如下:

0(OFF):关闭 Query Cache 功能,任何情况下都不会使用 Query Cache

1(ON):开启 Query Cache 功能,但是当 SELECT 语句中使用的 SQL_NO_CACHE 提示后,将不使用Query Cache

2(DEMAND):开启 Query Cache 功能,但是只有当 SELECT 语句中使用了 SQL_CACHE 提示后,才使用 Query Cache

mysql接收到一条select类型的query时,mysql会对这条query进行hash计算而得到一个hash值,然后通过该hash值到query cache中去匹配,如果没有匹配中,则将这个hash值存放在一个hash链表中,同时将query的结果集存放进cache中,存放hash值的链表的每一个hash节点存放了相应query结果集在cache中的地址,以及该query所涉及到的一些table的相关信息;如果通过hash值匹配到了一样的query,则直接将cache中相应的query结果集返回给客户端。如果mysql任何一个表中的任何一条数据发生了变化,便会通知query cache需要与该table相关的querycache全部失效,并释放占用的内存地址。

Mysql Query Cache优点很明显,对于一些频繁select querymysql直接从cache中返回相应的结果集,而不用再从表table中取出,减少了系统的IO开销。

即使Mysql Query Cache的收益很明显,但是也不能忽略其缺点:

1. query语句的hash计算和hash查找带来的资源消耗。mysql会对每条接收到的select类型的query进行hash计算然后查找该querycache是否存在,虽然hash计算和查找的效率已经足够高了,一条query所带来的消耗可以忽略,但一旦涉及到高并发,有成千上万条query时,hash计算和查找所带来的开销就的重视了;

2. query cache的失效问题。如果表变更比较频繁,则会造成query cache的失效率非常高。表变更不仅仅指表中的数据发生变化,还包括结构或者索引的任何变化;

3.对于不同sql但同一结果集的query都会被缓存,这样便会造成内存资源的过渡消耗。sql的字符大小写、空格或者注释的不同,缓存都是认为是不同的sql(因为他们的hash值会不同);

4. 相关参数设置不合理会造成大量内存碎片。

Mysql Query Cache有利有弊,合理的使用query cache可以使其发挥优势,并且有效的避开其劣势。

1. 并不是所有表都适合使用query cache。造成query cache失效的原因主要是相应的table发生了变更,那么就应该避免在变化频繁的table上使用query cache

2. 设置合理的参数变量和状态变量。

首先查看query cache的系统变量。

query_cache_limit:允许 Cache 的单条 Query 结果集的最大容量,默认是1MB,超过此参数设置的 Query 结果集将不会被 Cache

query_cache_min_res_unit:设置 Query Cache 中每次分配内存的最小空间大小,也就是每个 Query Cache 最小占用的内存空间大小

query_cache_size 表示系统中用于query cache的内存大小

query_cache_wlock_invalidate:控制当有写锁定发生在表上的时刻是否先失效该表相关的 Query Cache,如果设置为 1(TRUE),则在写锁定的同时将失效该表相关的所有 Query Cache,如果设置为0(FALSE)则在锁定时刻仍然允许读取该表相关的 Query Cache

查看query cache相关的状态变量

Qcache_free_blocks :表示query cache中目前还有多杀剩余的blocks,如果该值显示较大,则说明query cache中的内存碎片较多,需要进行整理了;

Qcache_free_memory :表示query cache目前剩余的内存大小;

Qcache_hits :表示query cache有多少次命中;

Qcache_inserts: 表示未命中cache后将结果集再写入到cache中的次数;

Qcache_lowmem_prunes: 表示多少条query因为内存不足而被清除出query_cache

Qcache_not_cached :表示因为query_cache_type的设置或者不能被cachequery的数量;

Qcache_queries_in_cache: 表示当前cachequery的数量;

Qcache_total_blocks :当前query cache中的block数量。

通过上述这些状态变量可以了解到query cache的运行状况,从而可以调整相应的系统参数的值。

总结:Mysql Query Cache的开启有利也有弊,在大量读少量写的业务场景下可以开启,否则建议关闭,关闭方法有两种,第一种:同时设置选项 query_cache_type = 0 query_cache_size = 0第二种:如果用源码编译MySQL的话,编译时增加参数 --without-query-cache 即可

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30109892/viewspace-2065371/,如需转载,请注明出处,否则将追究法律责任。

下一篇: 数据库字符集
请登录后发表评论 登录
全部评论

注册时间:2015-01-19

  • 博文量
    126
  • 访问量
    991975