设为首页 收藏本站
查看: 743|回复: 0

[经验分享] 高性能的MySQL(7)Query Cache 详解

[复制链接]

尚未签到

发表于 2018-10-1 12:00:19 | 显示全部楼层 |阅读模式
  MySQL查询缓存保存查询返回的完整结果。当查询命中该缓存,会立刻返回结果,跳过了解析,优化和执行阶段。
  查询缓存会跟踪查询中涉及的每个表,如果这写表发生变化,那么和这个表相关的所有缓存都将失效。
  但是随着服务器功能的强大,查询缓存也可能成为整个服务器的资源竞争单点。
  如何来判断打开查询缓存的好坏呢,就是本篇的内容~~~
  一、如何判断命中缓存
  缓存存放在一个引用表中,通过一个哈希值引用,这个哈希值包括查询本身,数据库,客户端协议的版本等,任何字符上的不同,例如空格,注释都会导致缓存不命中。
  当查询中有一些不确定的数据时,是不会缓存的,比方说now(),current_date(),自定义函数,存储函数,用户变量,字查询等。所以这样的查询也就不会命中缓存,但是还会去检测缓存的,因为查询缓存在解析SQL之前,所以MySQL并不知道查询中是否包含该类函数,只是不缓存,自然不会命中。
  打开Qcache对读和写都会带来额外的消耗:
  a、读查询开始之前必须检查是否命中缓存。
  b、如果读查询可以缓存,那么执行完之后会写入缓存。
  c、当向某个表写入数据的时候,必须将这个表所有的缓存设置为失效,如果缓存空间很大,则消耗也会很大,可能使系统僵死一段时间,因为这个操作是靠全局锁操作来保护的。
  对InnoDB表,当修改一个表时,设置了缓存失效,但是多版本特性会暂时将这修改对其他事务屏蔽,在这个事务提交之前,所有查询都无法使用缓存,直到这个事务被提交,所以长时间的事务,会大大降低查询缓存的命中。
  二、Qcache如何使用内存
  MySQL用于查询的缓存的内存被分成一个个变长数据块,用来存储类型,大小,数据等信息。
  当服务器启动的时候,会初始化缓存需要的内存,是一个完整的空闲块。当查询结果需要缓存的时候,先从空闲块中申请一个数据块大于参数query_cache_min_res_unit的配置,即使缓存数据很小,申请数据块也是这个,因为查询开始返回结果的时候就分配空间,此时无法预知结果多大。
  分配内存块需要先锁住空间块,所以操作很慢,MySQL会尽量避免这个操作,选择尽可能小的内存块,如果不够,继续申请,如果存储完时有空余则释放多余的。
DSC0000.png

  但是如果并发的操作,余下的需要回收的空间很小,小于query_cache_min_res_unit,不能再次被使用,就会产生碎片。如图:
DSC0001.png

  三、什么情况缓存发挥作用
  开启查询缓存可能是一个查询提高性能,但也可能影响其他查询。
  a、对于消耗很大的查询通常都是非常适合缓存的,例如汇总计算查询。
  b、对于update,delete,insert特别频繁的表不适合使用。
  一个判断查询缓存是否命中的直接数据是命中率,就是查询缓存返回结果占从查询的比率,当MySQL接受到一个查询的时候要么增加Qcache_hits的值要么增加Com_select的值。
  任何select没有命中缓存有以下一个可能
  a、查询语句包含函数或者结果太大超过配置无法被缓存。
  b、查询没有被缓存过。
  c、内存不足,被新的缓存替代,或者表的数据或结构变化。
  缓存碎片,内存不足,数据修改都会造成缓存失效。
  可以使用Qcache_lowmem_prunes来查看有多少失效是由于内存不足导致的。
  如果缓存的结果没有被任何select使用,那么这次缓存就是浪费时间和内存,可以通过查看Com_select和Qcache_inserts的值来看。如果每次查询都没有命中,然后查询结果还要写入缓存,那么这2个值应该差不多,而我们希望看到Qcache_inserts远远小于Com_select。
  这里推荐比较通用的一个指标来衡量缓存的打开和关闭:
  “命中和写入的比例”即Qcache_hits和Qcache_inserts的比值,最好能够达到10:1算是比较好的。
  四、如何配置和维护查询缓存
  先来看看我们的变量:
DSC0002.png

  query_cache_type:
  是否打开查询缓存。可以设置为ON,OFF,DEMAND。DEMAND表示只有在查询语句中使用SQL_CACHE和SQL_NO_CACHE来控制是否需要缓存。
  query_cache_size:
  查询缓存总空间,单位字节,必须是1024的整数倍。
  query_cache_min_res_unit:
  分配内存块时的最小单位。
  query_cache_limit:
  MySQL能够缓存的最大结果,超过的不会被缓存,Qcache_not_cached可以表示这个值。如果预先就知道结果很大不会被缓存,那么查询的时候加上SQL_NO_CACHE可以提高效率。
  query_cache_wlock_invalidate:
  如果某个表被锁住,是否返回缓存中的数据,默认关闭,也是建议的。
  减少碎片:
  合适的query_cache_min_res_unit可以减少碎片,这个参数最合适的大小和应用程序查询结果的平均大小直接相关,可以通过内存实际消耗(query_cache_size - Qcache_free_memory)除以Qcache_queries_in_cache计算平均缓存大小。
  可以通过Qcache_free_blocks来观察碎片,这个值反应了剩余的空闲块,如果这个值很多,但是
  Qcache_lowmem_prunes却不断增加,则说明碎片太多了。可以使用flush query cache整理碎片,重新排序,但不会清楚,清空命令是reset query cache。整理碎片期间,查询缓存无法被访问,可能导致服务器僵死一段时间,所以查询缓存不宜太大。
  提高查询缓存的使用率:
  如果碎片不是问题,命中率却非常低,可能是内存不足,可以通过 Qcache_free_memory 参数来查看没有使用的内存。
  如果2者都没有问题,命中率依然很低,那么说明缓存不适合你的当前系统。可以通过设置
  query_cache_size = 0或者query_cache_type 来关闭查询缓存。
DSC0003.png

  五、InnoDB的查询缓存
  事务是否可以访问查询缓存取决于当前事务的ID,以及对应表上是否有锁。
  当表上任何锁的时候,那么这个表的任何查询都无法被缓存的。
  a、所有大于表内存字典中的事务ID的才可以使用查询缓存。例如当前系统事务ID是5,那么1-4的事务是不能使用查询缓存的。
  b、实际上表的ID是系统版本号,所以当前事务自身后续的更新操作也无法都去和修改查询缓存。
  六、总结
  合理配置参数,或者使用SQL_CACHE和SQL_NO_CACHE来控制某个select是否需要进行缓存。
  对于写密集型的应用,建议关闭查询缓存。
  DONE!!!


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-607105-1-1.html 上篇帖子: mysql 错误log InnoDB: Error: pthread_create returned 11 下篇帖子: 安装&初始化mysql过程中的问题
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表