走进MySQL Query Cache的神秘世界 |
本文标签:MySQL Query Cache 最近经常有人问我 MySQL Query Cache 相关的问题,就整理一点MySQL Query Cache的内容,以供参考 。 顾名思义,MySQL Query Cache就是用来缓存和Query相关的数据的 。具体来说,Query Cache 缓存了我们客户端提交给 MySQL 的 SELECT 语句以及该语句的结果集 。大概来讲,就是将 SELECT 语句和语句的结果做了一个HASH 映射关系然后保存在一定的内存区域中 。 在大部分的MySQL分发版本中,Query Cache 功能默认都是打开的,我们可以通过调整 MySQL Server 的参数选项打开该功能 。主要由以下5个参数构成: ◆query_cache_limit:允许 Cache 的单条 Query 结果集的最大容量,默认是1MB,超过此参数设置的 Query 结果集将不会被 Cache 0(OFF):关闭 Query Cache 功能,任何情况下都不会使用 Query Cache Query Cache 如何处理子查询的? 这是我遇到的最为常见的一个问题 。其实 Query Cache 是以客户端请求提交的 Query 为对象来处理的,只要客户端请求的是一个 Query,无论这个 Query 是一个简单的单表查询还是多表 Join,亦或者是带有子查询的复杂 SQL,都被当作成一个 Query,不会被分拆成多个 Query 来进行 Cache 。所以,存在子查询的复杂 Query 也只会产生一个Cache对象,子查询不会产生单独的Cache内容 。UNION[ALL] 类型的语句也同样如此 。 Query Cache 是以 block 的方式存储的数据块吗? 不是,Query Cache 中缓存的内容仅仅只包含该 Query 所需要的结果数据,是结果集 。当然,并不仅仅只是结果数据,还包含与该结果相关的其他信息,比如产生该 Cache 的客户端连接的字符集,数据的字符集,客户端连接的 Default Database等 。 Query Cache 为什么效率会非常高,即使所有数据都可以 Cache 进内存的情况下,有些时候也不如使用 Query Cache 的效率高? Query Cache 的查找,是在 MySQL 接受到客户端请求后在对 Query 进行权限验证之后,SQL 解析之前 。也就是说,当 MySQL 接受到客户端的SQL后,仅仅只需要对其进行相应的权限验证后就会通过 Query Cache 来查找结果,甚至都不需要经过 Optimizer 模块进行执行计划的分析优化,更不许要发生任何存储引擎的交互,减少了大量的磁盘 IO 和 CPU 运算,所以效率非常高 。 客户端提交的 SQL 语句大小写对 Query Cache 有影响吗? 有,由于 Query Cache 在内存中是以 HASH 结构来进行映射,HASH 算法基础就是组成 SQL 语句的字符,所以必须要整个 SQL 语句在字符级别完全一致,才能在 Query Cache 中命中,即使多一个空格也不行 。 一个 SQL 语句在 Query Cache 中的内容,在什么情况下会失效? 为了保证 Query Cache 中的内容与是实际数据绝对一致,当表中的数据有任何变化,包括新增,修改,删除等,都会使所有引用到该表的 SQL 的 Query Cache 失效 。 为什么我的系统在开启了 Query Cache 之后整体性能反而下降了? 当开启了 Query Cache 之后,尤其是当我们的 query_cache_type 参数设置为 1 以后,MySQL 会对每个 SELECT 语句都进行 Query Cache 查找,查找操作虽然比较简单,但仍然也是要消耗一些 CPU 运算资源的 。而由于 Query Cache 的失效机制的特性,可能由于表上的数据变化比较频繁,大量的 Query Cache 频繁的被失效,所以 Query Cache 的命中率就可能比较低下 。所以有些场景下,Query Cache 不仅不能提高效率,反而可能造成负面影响 。 如何确认一个系统的 Query Cache 的运行是否健康,命中率如何,设置量是否足够? MySQL 提供了一系列的 Global Status 来记录 Query Cache 的当前状态,具体如下: ◆Qcache_free_blocks:目前还处于空闲状态的 Query Cache 中内存 Block 数目 可以根据这几个状态计算出 Cache 命中率,计算出 Query Cache 大小设置是否足够,总的来说,我个人不建议将 Query Cache 的大小设置超过256MB,这也是业界比较常用的做法 。 MySQL Cluster 是否可以使用 Query Cache? 其实在我们的生产环境中也没有使用 MySQL Cluster,所以我也没有在 MySQL Cluster 环境中使用 Query Cache 的实际经验,只是 MySQL 文档中说明确实可以在 MySQL Cluster 中使用 Query Cache 。从 MySQL Cluster 的原理来分析,也觉得应该可以使用,毕竟 SQL 节点和数据节点比较独立,各司其职,只是 Cache 的失效机制会要稍微复杂一点 。 原文链接:http://isky000.com/database/mysql-query-cache-summary |