一、概述

  MySQL Query Cache 会缓存select 查询,安装时默认是开启的,但是如果对表进行INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE, or DROP DATABASE等操作时,之前的缓存会无效并且删除。这样一定程度上也会影响我们数据库的性能。所以对一些频繁的变动表的情况开启缓存是不明智的。还有一种情况我们测试数据库性能的时候也要关闭缓存,避免缓存对我们测试数据的影响。

1.1、QueryCache的实现原理;

  1、目前只有select语句会被cache,其他类似show,use的语句则不会被cache。

  2、两个SQL语句,只要相差哪怕是一个字符(例如大小写不一样;多一个空格等),那么这两个SQL将使用不同的一个CACHE。

  但是会:

  • 过滤所有注释
  • 去掉SQL文本前後的空格,TAB等字符。注意,是文本前面和後面的。中间的不会被去掉。

  一个被频繁更新的表如果被应用了QC,可能会加重数据库的负担,而不是减轻负担。一般的做法是默认打开QC,而对一些涉及频繁更新的表的SQL语句加上SQL_NO_CACHE关键词来对其禁用CACHE。这样可以尽可能避免不必要的内存操作,尽可能保持内存的连续性。那些查询很分散的SQL语句,也不应该使用QC。例如用来查询用户和密码的语句——“select pass from user where name='surfchen'”。这样的语句,在一个系统里,很有可能只在一个用户登陆的时候被使用。每个用户的登陆所用到的查询,都是不一样的SQL文本,QC在这里就几乎不起作用了,因为缓存的数据几乎是不会被用到的,它们只会在内存里占地方。

1.2、QueryCache的负面影响:

1,Query的hash性能问题和命中率问题;
    2,查询缓存及其容易失效;当表内容发生变化或者表结构发生变化,对应的查询缓存内容都会失效;
    3,查询缓存中的结果容易产生重复;因为查询缓存中缓存的是查询结果,所以不同的查询的结果很容易重复;

1.3、Query Cache的使用:

1,设置query_cache_limit为查询缓存大小,如果为0,则不使用查询缓存;
    2,使用SQL_CACHE或者SQL_NO_CACHE来强制是否使用查询缓存;

如, 如果query_cache_type为1而又不想利用查询缓存中的数据,可以用下面的SQL:

SELECT SQL_NO_CACHE * FROM my_table WHERE condition;
    如果值为2,要使用缓存的话,需要使用SQL_CACHE开关参数:

SELECT SQL_CACHE * FROM my_table WHERE condition;

3,查询查询缓存设置:show variables like '%query_cache%';
        1,“have_query_cache”:该MySQL 是否支持Query Cache;按实际情况YES 或 NO
        2,“query_cache_limit”:Query Cache 存放的单条Query 最大Result Set ,默认1M;
        3,“query_cache_min_res_unit”:Query Cache 每个Result Set 存放的最小内存大小,默认4k;
        4,“query_cache_size”:系统中用于Query Cache 内存的大小;默认为0,表示为查询缓存预留的内存为0,则无法使用查询缓存。所以我们需要设置query_cache_size的值: 
        5,“query_cache_type”:系统是否打开了Query Cache 功能;默认为OFF

  

开始关闭缓存。关闭缓存有两种放法,一种临时的,一种永久的。

  临时的直接再命令行执行

  set global query_cache_size=0

  set global query_cache_type=0

永久的修改配置文件my.cnf ,添加下面的配置即可。

  query_cache_type=0

  query_cache_size=0

1.4、 查询查询缓存使用情况:show status like 'Qcache%';

1,“Qcache_free_blocks”:Query Cache 中目前还有多少剩余的blocks。如果该值显示较大,则说明Query Cache 中的内存碎片较多了
        2,“Qcache_free_memory”:Query Cache 中目前剩余的内存大小;
        3,“Qcache_hits”:多少次命中;
        4,“Qcache_inserts”:多少次未命中然后插入;Query Cache 命中率= Qcache_hits / ( Qcache_hits + Qcache_inserts );
        5,“Qcache_lowmem_prunes”:多少条Query 因为内存不足而被清除出Query Cache;
        6,“Qcache_not_cached”:因为query_cache_type 的设置或者不能被cache 的Query 的数量;
        7,“Qcache_queries_in_cache”:当前Query Cache 中cache 的Query 数量;
        8,“Qcache_total_blocks”:当前Query Cache 中的block 数量;

1.5、query cache的使用限制:

1,mysql query cache内容为 select 的结果集, cache 使用完整的 sql 字符串做 key, 并区分大小写,空格等。即两个sql必须完全一致才会导致cache命中。
        2,prepared statement永远不会cache到结果,即使参数完全一样,
        3,where条件中如包含了某些函数永远不会被cache, 比如current_date, now等。
        4,太大的result set不会被cache (< query_cache_limit)

1.6、query cache的使用方式:

1,如果没有绝对的使用把握,可以关闭查询缓存;【其实按照默认配置即可,推荐由DBA统一运维】
        2,如果要使用查询缓存,最好能够精确的控制那些表内容放到查询缓存,哪些表不用查询缓存;

注:存储块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的值。

1.7、排序缓冲

  当一个查询需要对结果进行排序的时候,MySQL会分配一定的内存用来排序。这个内存大小由sort_buffer_size来控制。记得,这个参数是针对每个查询的,而不是所有查询总共可分配的量。

  如果sort_buffer_size不够大,排序的结果将会被分段写入临时文件里。每次结束之後再把文件中的排序结果拿出来合并,进行再次排序,直到得出最後结果。sort_buffer_size越小,合并的次数就越多。合并次数可以通过状态变量Sort_merge_passes获得。理论上,Sort_merge_passes越小,排序越快。但是在实际应用中可能并非如此。sort_buffer_size如何设置需要根据实际运行环境来进行测试。如果实在不知道如何测试,那么就设到使Sort_merge_passes为0吧。

read_buffer_size read_rnd_buffer_size join_buffer_size thread_cache

1.8、字段类型推荐

这条语句可以根据当前表的内容来给出一个字段类型的推荐。

  select * from test_table_idx PROCEDURE ANALYSE();

上述参考自:http://blog.csdn.net/iris_xuting/article/details/50495928#t0

可以使用下面三个SQL来清理查询缓存: 
1、FLUSH QUERY CACHE; // 清理查询缓存内存碎片。
2、RESET QUERY CACHE; // 从查询缓存中移出所有查询。
3、FLUSH TABLES; //关闭所有打开的表,同时该操作将会清空查询缓存中的内容。

 

fsd

011-MySQL Query Cache 查询缓存设置操作的更多相关文章

  1. mysql query cache 查询缓存

    查看本博文,并进行验证(验证结果与博文一致): https://blog.csdn.net/carmazhao/article/details/7088530 mysql默认是开启查询缓存的. 设置查 ...

  2. MySQL Query Cache 相关的问题

    最近经常有人问我 MySQL Query Cache 相关的问题,就整理一点 MySQL Query Cache 的内容,以供参考. 顾名思义,MySQL Query Cache 就是用来缓存和 Qu ...

  3. MySQL查询缓存设置提高MySQL查询性能

    首先看看MSYQL逻辑框架:图片来自高性能mysql 如果使用了QueryCache,当查询接收到一个和之前同样的查询,服务器将会从查询缓存中检索结果,而不是再次分析和执行相同的查询.这样就能大大提高 ...

  4. MySql Query Cache 优化

    query cache原理 当mysql接收到一条select类型的query时,mysql会对这条query进行hash计算而得到一个hash值,然后通过该hash值到query cache中去匹配 ...

  5. mysql基础之查询缓存、存储引擎

    一.查询缓存 "查询缓存",就是将查询的结果缓存下载,如果查询语句完全相同,则直接返回缓存中的结果. 如果应用程序在某个场景中,需要经常执行大量的相同的查询,而且查询出的数据不会经 ...

  6. mysql 优化之查询缓存(mysql8已经废弃这个功能)

    对于缓存,一般人想到的是 redis.memcache 这些内存型的缓存. 但是实际上 mysql 也提供了缓存,mysql 里面的缓存是查询缓存,可以把我们查询过的语句缓存下来,下一次查询的时候有可 ...

  7. mysql优化-》查询缓存

    使用MySql查询缓存(query_cache_size) 在MySql中查询缓存的原理: 其实是MySql创建了一个临时的空间叫Qcache(这个空间生成在MySql的编译器内存中),这个空间的大小 ...

  8. 011 --Mysql中特定查询

    1.优化COUNT()查询 COUNT()可能是被大家误解最多的函数了,它有两种不同的作用,其一是统计某个列值的数量,其二是统计行数.统计列值时,要求列值是非空的,它不会统计NULL.如果确认括号中的 ...

  9. mysql实战优化之九:MySQL查询缓存总结

    mysql Query Cache 默认为打开.从某种程度可以提高查询的效果,但是未必是最优的解决方案,如果有的大量的修改和查询时,由于修改造成的cache失效,会给服务器造成很大的开销. mysql ...

随机推荐

  1. go build -tags 的使用

    go build 使用tag来实现编译不同的文件 go-tooling-workshop 中关于go build的讲解可以了解到go bulid的一些用法,这篇文章最后要求实现一个根据go bulid ...

  2. centos源码编译安装新版本内核

      在工作中,很多时候由于需要使用新的技术方案,需要较新版本的内核来支持新的功能,而centos系统自带的内核版本普遍都比较旧,因此我们需要对系统的内核进行升级,安装新版的内核.本文以centos7系 ...

  3. (八)Kubernetes Ingress资源

    前言 Kubernetes提供了两种内建的云端负载均衡机制(cloud load balancing)用于发布公共应用,一种是工作于传输层的Service资源,它实现的是“TCP负载均衡器”,另一种是 ...

  4. (一)Kubernetes 系统基础

    Kubernetes介绍 什么是Kubernetes? Kubernetes是容器集群管理系统,是一个开源的平台,可以实现容器集群的自动化部署.自动扩缩容.维护等功能. 使用Kubernetes可以: ...

  5. docker, docker-compose安装和使用

    官方文档: 安装docker: https://docs.docker.com/install/linux/docker-ce/centos/ 安装docker-compose: https://do ...

  6. cmds系统数据库源端大表数据更新优化

    cmds系统数据库源端大表数据更新优化 以下脚本可以用于将表按照rowid范围分区,获得指定数目的rowid Extent区间(Group sets of rows in the table into ...

  7. Redis Cluster数据分片机制

    复制粘贴自: https://www.e-learn.cn/content/redis/2344485, 点击链接访问原文 仅供个人学习参考之用, 如有侵权, 请联系删除! 高级开发不得不懂的Redi ...

  8. 搭建hadoop的HA集群模式(hadoop2.7.3+hive+spark)

    参考:http://blog.51cto.com/12824426/2177663?source=drh 一.集群的规划 Zookeeper集群:192.168.176.131 (bigdata112 ...

  9. SpringBoot 过滤器, 拦截器, 监听器 对比及使用场景

    1. 过滤器 (实现 javax.servlet.Filter 接口) ① 过滤器是在web应用启动的时候初始化一次, 在web应用停止的时候销毁. ② 可以对请求的URL进行过滤, 对敏感词过滤, ...

  10. JavaScript基础13——面向对象

    什么是面向对象? 面向对象(Object Oriented,OO)是软件开发方法.面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统,交互式界面,应用结构,应用平台,分布式系统,网络管 ...