摘自:http://jackyrong.iteye.com/blog/2173523

1 原理 
   MySQL查询缓存保存查询返回的完整结果。当查询命中该缓存,会立刻返回结果,跳过了解析,优化和执行阶段。 
查询缓存会跟踪查询中涉及的每个表,如果这写表发生变化,那么和这个表相关的所有缓存都将失效。

2 初步设置 
   默认这个开关是关闭的,就是禁止使用query_cache,查询是否使用语句如下:

mysql> show variables like '%query_cache%';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| have_query_cache | YES |
+------------------+-------+

注意这个只是显示,支持query_cache功能而已,默认是关闭的,通过这个语句 查询设置情况:

mysql>  show variables like '%query_cache_size%';
+------------------+---------+
| Variable_name | Value |
+------------------+---------+
| query_cache_size | |
+------------------+---------+
3  MYSQL如何分配query_cache_size 
    
mySQL用于查询的缓存的内存被分成一个个变长数据块,用来存储类型,大小,数据等信息。 
当服务器启动的时候,会初始化缓存需要的内存,是一个完整的空闲块。当查询结果需要缓存的时候,先从空闲块中申请一个数据块大于参数query_cache_min_res_unit的配置,
即使缓存数据很小,申请数据块也是这个,因为查询开始返回结果的时候就分配空间,此时无法预知结果多大。 
分配内存块需要先锁住空间块,所以操作很慢,MySQL会尽量避免这个操作,选择尽可能小的内存块,如果不够,继续申请,如果存储完时有空余则释放多余的。 
    
4  如何判断是否命中 
    缓存存放在一个引用表中,通过一个哈希值引用,这个哈希值包括查询本身,数据库,客户端协议的版本等,任何字符上的不同,例如空格,注释都会导致缓存不命中。 
当查询中有一些不确定的数据时,是不会缓存的,比方说now(),current_date(),自定义函数,存储函数,用户变量,字查询等。所以这样的查询也就不会命中缓存,
但是还会去检测缓存的,因为查询缓存在解析SQL之前,所以MySQL并不知道查询中是否包含该类函数,只是不缓存,自然不会命中。  打开Qcache对读和写都会带来额外的消耗: 
a、读查询开始之前必须检查是否命中缓存。 
b、如果读查询可以缓存,那么执行完之后会写入缓存。 
c、当向某个表写入数据的时候,必须将这个表所有的缓存设置为失效,如果缓存空间很大,则消耗也会很大,可能使系统僵死一段时间,因为这个操作是靠全局锁操作来保护的。 
对InnoDB表,当修改一个表时,设置了缓存失效,但是多版本特性会暂时将这修改对其他事务屏蔽,在这个事务提交之前,所有查询都无法使用缓存,直到这个事务被提交,所以长时间的事务,
会大大降低查询缓存的命中 一个表可以被许多类型的语句更改,例如INSERT、UPDATE、DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE。 
对于InnoDB而言,事物的一些特性还会限制查询缓存的使用。当在事物A中修改了B表时,因为在事物提交之前,对B表的修改对其他的事物而言是不可见的。为了保证缓存结果的正确性,
InnoDB采取的措施让所有涉及到该B表的查询在事物A提交之前是不可缓存的。如果A事物长时间运行,会严重影响查询缓存的命中率  查询缓存的空间不要设置的太大。 
因为查询缓存是靠一个全局锁操作保护的,如果查询缓存配置的内存比较大且里面存放了大量的查询结果,当查询缓存失效的时候,会长时间的持有这个全局锁。
因为查询缓存的命中检测操作以及缓存失效检测也都依赖这个全局锁,所以可能会导致系统僵死的情况 
mysql>  show status like '%Qcache%';
+-------------------------+---------+
| Variable_name | Value |
+-------------------------+---------+
| Qcache_free_blocks | |
| Qcache_free_memory | |
| Qcache_hits | |
| Qcache_inserts | |
| Qcache_lowmem_prunes | |
| Qcache_not_cached | |
| Qcache_queries_in_cache | |
| Qcache_total_blocks | |
+-------------------------+---------+
Qcache_free_blocks:表示查询缓存中目前还有多少剩余的blocks,如果该值显示较大,则说明查询缓存中的内存碎片过多了,可能在一定的时间进行整理。 

合适的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:查询缓存的内存大小,通过这个参数可以很清晰的知道当前系统的查询内存是否够用,是多了,还是不够用,DBA可以根据实际情况做出调整。  Qcache_hits:表示有多少次命中缓存。我们主要可以通过该值来验证我们的查询缓存的效果。数字越大,缓存效果越理想。  Qcache_inserts: 表示多少次未命中然后插入,意思是新来的SQL请求在缓存中未找到,不得不执行查询处理,执行查询处理后把结果insert到查询缓存中。这样的情况的次 数,次数越多,表示查询缓存应用到的比较少,效果也就不理想。当然系统刚启动后,查询缓存是空的,  Qcache_lowmem_prunes:该参数记录有多少条查询因为内存不足而被移除出查询缓存。通过这个值,用户可以适当的调整缓存大小。  Qcache_not_cached: 表示因为query_cache_type的设置而没有被缓存的查询数量。  Qcache_queries_in_cache:当前缓存中缓存的查询数量。  Qcache_total_blocks:当前缓存的block数量。   提高查询缓存的使用率: 
如果碎片不是问题,命中率却非常低,可能是内存不足,可以通过 Qcache_free_memory 参数来查看没有使用的内存。 
如果2者都没有问题,命中率依然很低,那么说明缓存不适合你的当前系统。可以通过设置 
query_cache_size = 0或者query_cache_type 来关闭查询缓存。  *****************************************************************************************************
mysql> show variables like '%query_cache%';
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| have_query_cache | YES |
| query_cache_limit | |
| query_cache_min_res_unit | |
| query_cache_size | |
| query_cache_strip_comments | OFF |
| query_cache_type | OFF |
| query_cache_wlock_invalidate | OFF |
+------------------------------+---------+

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

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

query_cache_size:设置 Query Cache 所使用的内存大小,默认值为0,大小必须是1024的整数倍,如果不是整数倍,MySQL 会自动调整降低最小量以达到1024的倍数

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

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


MySQL5.7 中的query_cache_size的更多相关文章

  1. WIN10安装和使用MySql5.6中遇到的一些问题与解决

    WIN10安装和使用MySql5.6中遇到的一些问题与解决 提示一下,安装前需要安装python环境. MySql安装缺少组件MySQL for Excel 如图(转载别人的图,自己的安装时没有截图) ...

  2. MySQL5.6中新增特性、不推荐使用的功能以及废弃的功能

    虽然已经使用MySQL5.6版本有一段时间了,但由于没有和之前的版本作过详细比较,所以对于哪些重要的或者不太重要的特性是在新版本中引入的,还有哪些特性已经或者将要从旧版本中移除的并没有一个十分全面的了 ...

  3. mysql5.7中timestam默认值'0000-00-00 00:00:00'报错

    在mysql5.7中设置 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'会报错: 解决办法: mysql> set sql_mode='NO_A ...

  4. MySQL5.7中InnoDB不可不知的新特性

    讲师介绍  赖铮 Oracle InnoDB团队 Principle Software Developer 曾任达梦.Teradata高级工程师,主要负责研发数据库执行引擎和存储引擎,十年以商数据库内 ...

  5. MySQL5.7中使用JSON(一)

    因为项目需要,存储字段存储成了JSON格式,在项目中是将查询出来的值通过jackson转成相应的bean进行处理的,觉得不够简单方便. 偶然下,知道了MYSQL5.7原生支持SQL,今天一回来就折腾安 ...

  6. mysql5.7中解决中文乱码的问题

    在使用mysql5.7时,会发现通过web端向数据库中写入中文后会出现乱码,但是在数据库中直接操作SQL语句插入数据后中文就显示正常,这个问题怎么解决呢?此处不对mysql的数据编码过程和原理进行讲解 ...

  7. MySQL5.7中使用JSON

    一.创建表 CREATE TABLE `user` ( `uid` int(11) NOT NULL AUTO_INCREMENT, `info` json DEFAULT NULL, #注意desc ...

  8. Centos6.6上安装mysql5.6中的一些典型问题

    经过两天的摸索,终于成功在CentOS6.6系统上成功安装了mysql5.6,现整理如下. (1)安装时的问题: 最小化安装后,安装rpm包时经常会遇到 linux/centos Header V3 ...

  9. MySQL5.6中date和string的转换和比较

    Conversion & Comparison, involving strings and dates in MySQL 5.6 我们有张表,表中有一个字段dpt_date,SQL类型为da ...

随机推荐

  1. Java程序运行原理

    概念介绍: ![file](https://img2018.cnblogs.com/blog/1454321/202001/1454321-20200104145655999-149562495.jp ...

  2. The Annual Summary Of 2019

    Time is flying, it arrives at the end of year again. This is my first year working in PinDuoDuo inc ...

  3. 低功耗蓝牙(BLE)——概念

    1. 种类 单模蓝牙:仅支持传统蓝牙和BLE(低功耗蓝牙)中的一种: 双模蓝牙:同时支持传统蓝牙和BLE(低功耗蓝牙). 2. 部署方案 3. 节点类型 根据蓝牙协议不同的协议层有不同的角色 1. S ...

  4. Java类成员之方法

    方法含义: 1. 方法是类或对象行为特征的抽象,用来完成某个功能操作. 2.在某些语言中也称为函数或过程. 3.将功能封装为方法的目的是简化代码,可以实现代码重用. 4.在Java里的方法不能独立存在 ...

  5. 集合下篇—Map和Set 源码分析

    Map Map不同于Collection集合,Map存放的是键值对,且键不能重复 1 .HashMap (底层是哈希表,Java中用链表的数组实现,存取顺序不一致) 这篇博客主要讲集合的,哈希表这样的 ...

  6. 使用Merkle树检测数据不一致(翻译)

    背景 Cassandra的逆熵功能使用Merkle树来检测副本之间的数据不一致. 定义 Merkle树是一种哈希树,其中的叶子包含各个数据块的哈希值,父节点包含其各自的子节点的哈希值.它提供了一种有效 ...

  7. 求二叉树的深度,从根节点到叶子节点的最大值,以及最大路径(python代码实现)

    首先定义一个节点类,包含三个成员变量,分别是节点值,左指针,右指针,如下代码所示: class Node(object): def __init__(self, value): self.value ...

  8. codeforces 上的找两人的幸运天

    Bob and Alice are often participating in various programming competitions. Like many competitive pro ...

  9. Spring Cloud Eureka------详解

    一 Eureka服务治理体系 1.1 服务治理 服务治理是微服务架构中最为核心和基础的模块,它主要用来实现各个微服务实例的自动化注册和发现. Spring Cloud Eureka是Spring Cl ...

  10. python爬虫——selenium+chrome使用代理

    先看下本文中的知识点: python selenium库安装 chrome webdirver的下载安装 selenium+chrome使用代理 进阶学习 搭建开发环境: selenium库 chro ...