QueryCache(下面简称QC)是根据SQL语句来cache的。一个SQL查询如果以select开头,那么MySQL服务器将尝试对其使用QC。每个Cache都是以SQL文本作为key来存的。在应用QC之前,SQL文本不会被作任何处理。也就是说,两个SQL语句,只要相差哪怕是一个字符(例如大小写不一样;多一个空格等),那么这两个SQL将使用不同的一个CACHE。

不过SQL文本有可能会被客户端做一些处理。例如在官方的命令行客户端里,在发送SQL给服务器之前,会做如下处理: 过滤所有注释 去掉SQL文本前后的空格,TAB等字符。注意,是文本前面和后面的。中间的不会被去掉。 下面的三条SQL里,因为SELECT大小写的关系,最后一条和其他两条在QC里肯定是用的不一样的存储位置。而第一条和第二条,区别在于后者有个注释,在不同客户端,会有不一样的结果。所以,保险起见,请尽量不要使用动态的注释。在PHP的mysql扩展里,SQL的注释是不会被去掉的。也就是三条SQL会被存储在三个不同的缓存里,虽然它们的结果都是一样的。 select * FROM people where name='surfchen'; select * FROM people where /*hey~*/name='surfchen'; SELECT * FROM people where name='surfchen'; 目前只有select语句会被cache,其他类似show,use的语句则不会被cache。 因为QC是如此前端,如此简单的一个缓存系统,所以如果一个表被更新,那么和这个表相关的SQL的所有QC都会被失效。假设一个联合查询里涉及到了表A和表B,如果表A或者表B的其中一个被更新(update或者delete),这个查询的QC将会失效。 也就是说,如果一个表被频繁更新,那么就要考虑清楚究竟是否应该对相关的一些SQL进行QC了。一个被频繁更新的表如果被应用了QC,可能会加重数据库的负担,而不是减轻负担。我一般的做法是默认打开QC,而对一些涉及频繁更新的表的SQL语句加上SQL_NO_CACHE关键词来对其禁用CACHE。这样可以尽可能避免不必要的内存操作,尽可能保持内存的连续性。 那些查询很分散的SQL语句,也不应该使用QC。例如用来查询用户和密码的语句——“select pass from user where name='surfchen'”。这样的语句,在一个系统里,很有可能只在一个用户登陆的时候被使用。每个用户的登陆所用到的查询,都是不一样的SQL文本,QC在这里就几乎不起作用了,因为缓存的数据几乎是不会被用到的,它们只会在内存里占地方。

存储块 在本节里“存储块”和“block”是同一个意思 QC缓存一个查询结果的时候,一般情况下不是一次性地分配足够多的内存来缓存结果的。而是在查询结果获得的过程中,逐块存储。当一个存储块被填满之后,一个新的存储块将会被创建,并分配内存(allocate)。单个存储块的内存分配大小通过query_cache_min_res_unit参数控制,默认为4KB。最后一个存储块,如果不能被全部利用,那么没使用的内存将会被释放。如果被缓存的结果很大,那么会可能会导致分配内存操作太频繁,系统系能也随之下降;而如果被缓存的结果都很小,那么可能会导致内存碎片过多,这些碎片如果太小,就很有可能不能再被分配使用。 除了查询结果需要存储块之外,每个SQL文本也需要一个存储块,而涉及到的表也需要一个存储块(表的存储块是所有线程共享的,每个表只需要一个存储块)。存储块总数量=查询结果数量*2+涉及的数据库表数量。也就是说,第一个缓存生成的时候,至少需要三个存储块:表信息存储块,SQL文本存储块,查询结果存储块。而第二个查询如果用的是同一个表,那么最少只需要两个存储块:SQL文本存储块,查询结果存储块。 通过观察Qcache_queries_in_cache和Qcache_total_blocks可以知道平均每个缓存结果占用的存储块。它们的比例如果接近1:2,则说明当前的query_cache_min_res_unit参数已经足够大了。如果Qcache_total_blocks比Qcache_queries_in_cache多很多,则需要增加query_cache_min_res_unit的大小。 Qcache_queries_in_cache*query_cache_min_res_unit(sql文本和表信息所在的block占用的内存很小,可以忽略)如果远远大于query_cache_size-Qcache_free_memory,那么可以尝试减小query_cache_min_res_unit的值。

调整大小 如果Qcache_lowmem_prunes增长迅速,意味着很多缓存因为内存不够而被释放,而不是因为相关表被更新。尝试加大query_cache_size,尽量使Qcache_lowmem_prunes零增长。

启动参数 show variables like 'query_cache%'可以看到这些信息。 query_cache_limit:如果单个查询结果大于这个值,则不Cache query_cache_size:分配给QC的内存。如果设为0,则相当于禁用QC。要注意QC必须使用大约40KB来存储它的结构,如果设定小于40KB,则相当于禁用QC。QC存储的最小单位是1024 byte,所以如果你设定了一个不是1024的倍数的值,这个值会被四舍五入到最接近当前值的等于1024的倍数的值。 query_cache_type:0 完全禁止QC,不受SQL语句控制(另外可能要注意的是,即使这里禁用,上面一个参数所设定的内存大小还是会被分配);1启用QC,可以在SQL语句使用SQL_NO_CACHE禁用;2可以在SQL语句使用SQL_CACHE启用。 query_cache_min_res_unit:每次给QC结果分配内存的大小

状态 show status like 'Qcache%'可以看到这些信息。 Qcache_free_blocks:当一个表被更新之后,和它相关的cache blocks将被free。但是这个block依然可能存在队列中,除非是在队列的尾部。这些blocks将会被统计到这个值来。可以用FLUSH QUERY CACHE语句来清空free blocks。 Qcache_free_memory:可用内存,如果很小,考虑增加query_cache_size Qcache_hits:自mysql进程启动起,cache的命中数量 Qcache_inserts:自mysql进程启动起,被增加进QC的数量 Qcache_lowmem_prunes:由于内存过少而导致QC被删除的条数。加大query_cache_size,尽可能保持这个值0增长。 Qcache_not_cached:自mysql进程启动起,没有被cache的只读查询数量(包括select,show,use,desc等) Qcache_queries_in_cache:当前被cache的SQL数量 Qcache_total_blocks:在QC中的blocks数。一个query可能被多个blocks存储,而这几个blocks中的最后一个,未用满的内存将会被释放掉。例如一个QC结果要占6KB内存,如果query_cache_min_res_unit是4KB,则最后将会生成3个blocks,第一个block用来存储sql语句文本,这个不会被统计到query+cache_size里,第二个block为4KB,第三个block为2KB(先allocate4KB,然后释放多余的2KB)。每个表,当第一个和它有关的SQL查询被CACHE的时候,会使用一个block来存储表信息。也就是说,block会被用在三处地方:表信息,SQL文本,查询结果。

mysql query 原理_[转]MySQL的Query Cache原理相关推荐

  1. MySQL学习笔记_关于MySQL的字符类型VARCHAR长度知识总结

    MySQL学习笔记_关于MySQL的字符类型VARCHAR长度知识总结 一.VARCHAR存储和行长度限制 1.VARCHAR(N)中,N指的是字符的长度,VARCHAR类型最大支持65535,指的是 ...

  2. mysql新增字段位置_图解MySQL | [原理解析] MySQL 为表添加列 是怎么quot;立刻quot;完成的...

    在上一期图解 图解MySQL | MySQL DDL为什么成本高?中,我们介绍了: 传统情况下,为表添加列需要对表进行重建 腾讯团队为 MySQL 引入了 Instant Add Column 的方案 ...

  3. mysql sum 慢_故障分析 | MySQL 优化案例 - select count(*)

    作者:xuty 本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源. 本文关键字:count.SQL.二级索引 一.故事背景 项目组联系我说是有一张 50 ...

  4. 安装版 修改mysql最大连接数_修改MySQL最大连接数

    方法一: 进入MySQL安装目录 打开MySQL配置文件 my.ini 或 my.cnf查找 max_connections=100 修改为 max_connections=1000 服务里重起MyS ...

  5. mysql 关闭主从_取消mysql主从复制关系

    mysql主从复制中,需要将主从复制关系清除,需要取消其从库角色.这可通过执行RESET SLAVE ALL清除从库的同步复制信息.包括连接信息和二进制文件名.位置.从库上执行这个命令后,使用show ...

  6. 哪些是能安装mysql的文件_安装mysql详细步骤有哪些?

    安装mysql详细步骤有哪些? 安装mysql详细步骤有: MySQL下载 进入页面官网,找到下载页面页面下拉,找到如下图,然后点击下载Windows (x86, 64-bit), ZIP Archi ...

  7. mysql insert 字符集_有关 MySQL 字符集的注意事项-爱可生

    本文关键字:字符集.建库建表 一.数据库和字符集 1. 建库时指定 创建数据库时,显式指定字符集和排序规则,同时,当切换到当前数据库后,参数 character_set_database,collat ...

  8. mysql binlog 备份_做好mysql运维,必须熟练掌握备份和恢复,实战一次不行多来几次...

    原文:https://www.toutiao.com/i6855460778359816715/ 平台:头条 作者:程序员不就是0和1 一. 备份恢复策略 进行备份或恢复操作时需要考虑一些因素: 1. ...

  9. mysql 主主结构_高性能mysql主主架构

    (3)配置参数说明 server-id:ID值唯一的标识了复制群集中的主从服务器,因此它们必须各不相同.master_id必须为1到232–1之间的一个正整数值,slave_id值必须为2到232–1 ...

  10. mysql varchar 效率_由MySQL中char和varchar效率想到的

    对比char和varchar随便在google或百度中搜一下得到的结论大概都是"char定长,varchar不定长,char要比varchar占用更多的空间,由于定长char的效率高于var ...

最新文章

  1. AMT:管理咨询冲击“最后一公里”
  2. 深入剖析.NET运行机制
  3. 数据中心基础设施运维是什么?
  4. 【TensorFlow】——broadcast_to(在不复制内存的情况下自动扩张tensor)
  5. 鸟哥的linux私房菜简答题答案,《鸟哥的Linux私房菜》7章 Linux文件与目录管理 习题答案...
  6. golang []byte和string相互转换
  7. 联手三年,获取数千名客户,阿里云如何重构Elastic开放免费的技术?
  8. vi编辑器 末尾添加_VI编辑器的使用方法
  9. 从快感到成就感:多巴胺vs内啡肽
  10. elasticsearch7.5.0 集群部署
  11. matlab的RI是什么,LTE上报的CQI、PMI、RI分别有什么用
  12. 可能是最通俗的Lempel-Ziv-Welch (LZW)无损压缩算法详述
  13. python数字图像处理以及绘图
  14. 谷歌中国大范围招兵买马:涉及销售和研发等多个部门
  15. 从GraalVM到Quarkus系列-B002篇-Quarkus中的字节码框架gizmo
  16. 实验(1)信号的采样
  17. 【C++代码】区间重叠问题
  18. 请问怎么设置默认浏览器
  19. fabric cello
  20. 6种java垃圾回收算法_Java垃圾回收机制

热门文章

  1. [TODO]com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method
  2. AttributeError: 'dict' object has no attribute 'iteritems' python3报错
  3. (转)深入理解Linux修改hostname
  4. C# mysql 链接 遇到 异常 Authentication with old password no longer supported, use 4.1 style passwords....
  5. C++ vector容器类型 (转)
  6. Flutter 饼状图、柱状图、拆线图、Flutter动态饼图、Flutter图表 flutter_echart 开发文档
  7. Flutter实现倒计时功能
  8. 爬虫之操作excel
  9. “unauthorized: authentication required” -- openshift3.9 docker push 报错
  10. 【bzoj1222】[HNOI2001]产品加工 背包dp