您的位置:首页 > 产品设计 > UI/UE

[MySQL] 浅谈 MySQL Query Cache

2016-10-13 14:56 351 查看
Query Cache

就是把 “查询返回的结果” 缓存起来。

但“查询返回的结果” 其实不准确,MySQL 还会缓存查询语句。并在内存中把“查询语句”及“返回的结果集” 映射起来。

Query Cache 默认为打开。

主要参数有:
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

?

1. Query Cache 与 查询

无论 MySQL收到的 Query 是单表还是多表或是包含子查询的 SQL,都被作为一个 Query,不会被分拆成多个 Query 来进行 Cache。

包括Union 语句。

2. Query Cache 是以 block 的方式存储的数据块吗?

不是,Query Cache 中缓存的内容只与结果集相关。(还cache了结果相关的其他信息)

3. Query Cache 为什么效率会非常高,即使所有数据都可以 Cache 进内存的情况下,有些时候也不如使用 Query Cache 的效率高?

Query Cache 的查找,是在 MySQL 接受到客户端请求后在对 Query 进行权限验证之后,SQL 解析之前。

也就是说,当 MySQL 接收到客户端的SQL后,仅仅只需要对其进行相应的权限验证后就会通过 Query Cache 来查找结果,甚至都不需要经过 Optimizer 模块进行执行计划的分析优化,更不许要发生任何存储引擎的交互,减少了大量的磁盘 IO 和 CPU 运算,所以效率非常高。

4. 客户端提交的 SQL 语句大小写对 Query Cache 有影响吗?

有,由于 Query Cache 在内存中是以 HASH 结构来进行映射,HASH 算法基础就是组成 SQL 语句的字符,所以必须要整个 SQL 语句在字符级别完全一致,才能在
Query Cache 中命中。

5. 一个 SQL 语句在 Query Cache 中的内容,在什么情况下会失效?

为了保证 Query Cache 中的内容与是实际数据绝对一致,当表中的数据有任何变化,包括新增,修改,删除等,都会使所有引用到该表的 SQL 的 Query Cache 失效。

6. 为什么我的系统在开启了 Query Cache 之后整体性能反而下降了?

当开启了 Query Cache 之后,尤其是当我们的 query_cache_type 参数设置为 1 以后,MySQL 会对每个 SELECT 语句都进行 Query Cache 查找,查找操作虽然比较简单,但仍然也是要消耗一些 CPU 运算资源的。而由于 Query Cache 的失效机制的特性,可能由于表上的数据变化比较频繁,大量的 Query Cache 频繁的被失效,所以 Query Cache 的命中率就可能比较低下。所以有些场景下,Query Cache 不仅不能提高效率,反而可能造成负面影响。

7. 如何确认一个系统的 Query Cache 的运行是否健康,命中率如何,设置量是否足够?

MySQL 提供了一系列的 Global Status 来记录 Query Cache 的当前状态,具体如下:

Qcache_free_blocks:目前还处于空闲状态的 Query Cache 中内存 Block 数目

Qcache_free_memory:目前还处于空闲状态的 Query Cache 内存总量

Qcache_hits:Query Cache 命中次数

Qcache_inserts:向 Query Cache 中插入新的 Query Cache 的次数,也就是没有命中的次数

Qcache_lowmem_prunes:当 Query Cache 内存容量不够,需要从中删除老的 Query Cache 以给新的 Cache 对象使用的次数

Qcache_not_cached:没有被 Cache 的 SQL 数,包括无法被 Cache 的 SQL 以及由于
query_cache_type 设置的不会被 Cache 的 SQL

Qcache_queries_in_cache:目前在 Query Cache 中的 SQL 数量

Qcache_total_blocks:Query Cache 中总的 Block 数量

可以根据这几个状态计算出 Cache 命中率,计算出 Query Cache 大小设置是否足够,一般来说,不建议将 Query Cache 的大小设置超过256MB,这也是业界比较常用的做法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: