[MySQL FAQ]系列 — 线上环境到底要不要开启query cache

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: [MySQL FAQ]系列 — 线上环境到底要不要开启query cache

Query Cache(查询缓存,以下简称QC)存储SELECT语句及其产生的数据结果,特别适用于:频繁提交同一个语句,并且该表数据变化不是很频繁的场景,例如一些静态页面,或者页面中的某块不经常发生变化的信息。QC有可能会从InnoDB Buffer Pool或者MyISAM key buffer里读取结果。


由于QC需要缓存最新数据结果,因此表数据发生任何变化(INSERT、UPDATE、DELETE或其他可能产生数据变化的操作),都会导致QC被刷新。


根据MySQL官方的测试,QC的优劣分别是:

1、如果对一个表执行简单的查询,但每次查询都不一样的话,打开QC后,性能反而下降了13%左右。但通常实际业务中,通常不会只有这种请求,因此实际影响应该比这个小一些。


2、如果对一个只有一行数据的表进行查询,则可以提升238%,这个效果还是非常不错的。

因此,如果是在一个更新频率非常低而只读查询频率非常高的场景下,打开QC还是比较有优势的,其他场景下,则不建议使用。而且,QC一般也维持在100MB以内就够了,没必要设置超过数百MB。


QC严格要求2次SQL请求要完全一样,包括SQL语句,连接的数据库、协议版本、字符集等因素都会影响,下面几个例子中的SQL会被认为是完全不一样而不会使用同一个QC内存块:

mysql> set names latin1; SELECT * FROM table_name;

mysql> set names latin1; select * from table_name;

mysql> set names utf8; select * from table_name;


此外,QC也不适用于下面几个场景:

1、子查询或者外层查询;

2、存储过程、存储函数、触发器、event中调用的SQL,或者引用到这些结果的;

3、包含一些特殊函数时,例如:BENCHMARK()、CURDATE()、CURRENT_TIMESTAMP()、NOW()、RAND()、UUID()等等;

4、读取mysql、INFORMATION_SCHEMA、performance_schema 库数据的;

5、类似SELECT…LOCK IN SHARE MODE、SELECT…FOR UPDATE、SELECT..INTO OUTFILE/DUMPFILE、SELECT..WHRE…IS NULL等语句;

6、SELECT执行计划用到临时表(TEMPORARY TABLE);

7、未引用任何表的查询,例如 SELECT 1+1 这种;

8、产生了 warnings 的查询;

9、SELECT语句里加了 SQL_NO_CACHE 关键字;


更加奇葩的是,MySQL在从QC中取回结果前,会先判断执行SQL的用户是否有全部库、表的SELECT权限,如果没有,则也不会使用QC。


相比下面这个,其实上面所说的都不重要。


最为重要的是,在MySQL里QC是由一个全局锁在控制,每次更新QC的内存块都需要进行锁定


例如,一次查询结果是20KB,当前 query_cache_min_res_unit 值设置为 4KB(默认值就是4KB,可调整),那么么本次查询结果共需要分为5次写入QC,每次都要锁定,可见其成本有多高。


我们可以通过 PROFILING 功能来查看 QC 相关的一些锁竞争,例如像下面这样的:

  • Waiting for query cache lock

  • Waiting on query cache mutex


或者,也可以通过执行 SHOW PROCESSLIST 来看线程的状态,例如:


• checking privileges on cached query

检查用户是否有权限读取QC中的结果集


• checking query cache for query

检查本次查询结果是否已经存储在QC中


• invalidating query cache entries

由于相关表数据已经修改了,因此将QC中的内存记录被标记为失效


• sending cached result to client

从QC中,将缓存后的结果返回给客户程序


• storing result in query cache

将查询结果缓存到QC中

如果可以频繁看到上述几种状态,那么说明当前QC基本存在比较重的竞争。


说了这么多废话,其实核心要点就一个:

如果线上环境中99%以上都是只读,很少有更新,再考虑开启QC吧,否则,就别开了。

关闭方法很简单,有两种:

1、同时设置选项 query_cache_type = 0query_cache_size = 0

2、如果用源码编译MySQL的话,编译时增加参数 --without-query-cache 即可;


延伸阅读:

http://www.dbasquare.com/kb/how-query-cache-can-cause-performance-problems/

http://www.percona.com/blog/2012/09/05/write-contentions-on-the-query-cache/

http://dev.mysql.com/doc/refman/5.6/en/query-cache.html

            </div>
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
SQL 关系型数据库 MySQL
MySql5.6版本开启慢SQL功能-本次采用永久生效方式
MySql5.6版本开启慢SQL功能-本次采用永久生效方式
41 0
|
安全 Python Windows
python - http请求带Authorization
# 背景 接入公司的一个数据统计平台,该平台的接口是带上了Authorization验证方式来保证验签计算安全   # 方法 其实很简单,就是在header中加入key=Authorization,value是协商好的协议即可; 如,我们这边是base64.
4669 0
|
SQL 关系型数据库 MySQL
MySQL中sp运行check表版本更新流程解析
MySQL中sp运行check表版本更新流程解析
233 0
|
关系型数据库 MySQL 测试技术
[MySQL FAQ]系列 — 打开general log到底影响多大
[MySQL FAQ]系列 — 打开general log到底影响多大
127 0
[MySQL FAQ]系列 — 打开general log到底影响多大
|
SQL 存储 缓存
[MySQL FAQ]系列 — 线上环境到底要不要开启query cache
[MySQL FAQ]系列 — 线上环境到底要不要开启query cache
106 0
|
关系型数据库 MySQL OLTP
[MySQL FAQ]系列 — 为什么要关闭query cache,如何关闭
[MySQL FAQ]系列 — 为什么要关闭query cache,如何关闭
144 0
|
SQL 存储 关系型数据库
[MySQL FAQ]系列 — PROFILING中要关注哪些信息
[MySQL FAQ]系列 — PROFILING中要关注哪些信息
115 0
比hexo更好用的轻量级博客,5分钟部署上线!
比hexo更好用的轻量级博客,5分钟部署上线!
比hexo更好用的轻量级博客,5分钟部署上线!
|
SQL 存储 安全
都这么卷了,不懂MyBatis插件开发怎么行,教你实现一个MyBatis分页插件
MyBatis可谓是Java开发工程师必须要掌握的持久层框架,它能够让我们更容易的通过Java代码操作数据库,并且它还有很高的扩展性,我们可以自定义插件,去让MyBatis的功能变的更为强大,本篇文章我们就以打印SQL,SQL分页为例,来讲一下如何开发MyBatis的插件。
424 0
|
算法 搜索推荐