从遇到的一个性能问题学习mysql的查询缓存

原创 2018年04月16日 01:20:33

最近在测试性能问题的时候,遇到一个加压TPS无法上去的接口;接口很简单,就是触发一个mysql的查询语句并放回。TPS在加压后上不去;观察服务节点和数据库节点的资源使用情况都正常。一时分析不出是什么原因。

猜测是不是命中了数据库缓存导致的。引起对mysql缓存的了解。记录下一些学习的点,零散。问题还没找到,等找到了再记录下吧。

首先是存储引擎:

mysql有多种存储引擎,但是我遇到的是innodb。所以就基于innodb学习下它的一些查询缓存相关的。innodb采用了聚簇索引,提高了主键查询的性能,同时要求2级索引必须包含主键,也就加大了索引文件。它有很多优点,这里不列举,去看看N多大神的帖子也就知道了。

什么是查询缓存:

是指mysql在内存中缓存了完整的select语句的结果。不过select语句中不能带函数和变量,否则就无法匹配到,会造成缓存无法命中。单查询命中缓存时会立刻返回结果,跳过了解析,优化,执行的阶段。也就是这点,我在观察性能脚本执行过程中,show full processlist没看到执行的语句,IO也比较低。所以产生了这种怀疑,只是目前还没找到方法去证明是命中缓存导致的测试现象。

mysql是怎么判断是否命中缓存:

首先mysql会将第一次查询的结果放在一个引用表中,通过哈希引用;当一个查询过来的时候,会通过一些判断条件去判断。当命中时,就不会去解析这条sql,而是按照缓存结果返回。但是sql语句中有任何不确定的函数,变量,和不统一的写法(空格之类的不一致)都无法命中缓存。

缓存的应用只有性能的提升就没有消耗?

答案是否定的,在提升查询的性能的同时,其实会带来读写的消耗:

1、读操作的时候,会先去检查是否会命中缓存

2、如果查询能缓存,则会在返回结果后,检查这个查询语句是否已经缓存了,如果没有缓存,则写入缓存

3、对于数据库的写操作,由于可能改变原来查询的结果;这时候需要先去将对应表的缓存设置为失效的状态。如果缓存大或者碎片过多,这消耗了系统的性能。

如何用内存的:

在数据库在启动创建数据库缓存时,根据配置申请一块内存块,初始化后用于存储数据缓存。主要包括数据块索引,数据,状态等的维护。

怎么判断是否需要开启查询缓存?

最直接的方法,分别在开启和不开启的情况下进行性能测试。然后就是决策,因为在某些sql的查询性能的提升后,可能同时会带来其他sql的执行性能下降。这时候需要决策哪个更重要。

哪些场景适合开启查询缓存:

那种查询基础数据量很大,结果却返回很小的。例如count(),max(),等。

如何判断缓存命中率:

可以试试看两个值,任何查询,要么使Qcache_hits增加,要么使Com_select值增加。可以通过(Qcache_hits/(Qcache_hits+Com_select))进行计算。至于这个命中率怎么样才是好的,却没有定论。需要根据自己的系统决定。唯一的一条原则就是,它带来的性能提升比它带来的性能损耗要高即可。

至于缓存未命中:

缓存未命中的原因主要有:

1、查询无法缓存

2、第一次查询

3、内存不足导致之前的缓存被清理了,即失效了。

缓存的配置:

缓存的使用需要在mysql的配置文件中进行配置:

1、query_cache_type:是否打开查询缓存:ON,OFF,DEMAND,其中DEMAND是只有查询语句中明确洗了SQL_CACHE才放入查询缓存。

2、query_cache_size:查询缓存使用的总内存大小

3、query_cache_min_res_unit:查询缓存中分配内存块是最小的单位

4、query_cache_limit:能缓存的最大内存

5、query_cache_wlock_invalidate:如果某个数据表被其他的链接锁住,是否仍然从查询缓存中返回结果。

Innodb和缓存:

innodb有事务机制,通过事务ID的判断来判断是否该查询能用缓存。只有当前的事务ID小于即将执行的事务ID才给该事务使用缓存。同时这个表如果有任何的锁,都不能用缓存。即加锁的事务不允许用查询缓存。

看到这里好像差不多了,但是我发现原来被测系统的缓存时OFF状态。那是不是还有其他缓存机制?

有的:

包括应用层缓存,handlerSocket与memchached三种。还没弄懂,夜深。后面继续。

所以,那个性能问题到底是什么问题,目前主要还是觉得读的缓存。未完待续。。。

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

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

MySQL 学习过程遇到的问题

系统:win32 位 MySQL 版本:5.7.17-log MySQL 语法对大小写不敏感,但是大写更容易看出。 一、启动关闭MySQL服务 1【开始菜单】搜索 services...
  • qq_26776873
  • qq_26776873
  • 2017-07-18 17:40:41
  • 160

MySQL查询缓存总结

可以通过下面的SQL查看当前查询缓存相关参数状态: SHOW VARIABLES LIKE '%query_cache%'; 输出结果类似下面:    qu...
  • PHPService
  • PHPService
  • 2015-07-05 19:45:12
  • 4231

启用MySQL查询缓存

启用MySQL查询缓存可以极大地减低数据库服务器的CPU使用率,实际使用情况是:开启前CPU使用率120%左右,开启后降到了10%。 查看查询缓存情况: mysql> show v...
  • ClementAD
  • ClementAD
  • 2015-07-08 17:42:27
  • 7764

MySQL学习错误总结篇:遇到并处理过的错误-持续更新

记录学习MySQL过程中遇到并处理过的一些异常——持续更新 1.MySQL安装报错(博文http://blog.csdn.net/hwhmh2010/article/details/52984890中...
  • hwhmh2010
  • hwhmh2010
  • 2016-11-15 21:24:51
  • 230

Mysql 查询缓存

Mysql 查询缓存 查询缓存的作用就是当查询接收到一个和之前同样的查询,服务器将会从查询缓存种检索结果,而不是再次分析和执行上次的查询。这样就大大提高了性能,节省时间。 1.配置查询缓存 修改配置...
  • orangeholic
  • orangeholic
  • 2014-09-03 11:28:08
  • 1640

mysql 开启查询缓存方法与查询例子

开启缓存,设置缓存大小,具体实施如下: 1、修改配置文件,windows下是my.ini,linux下是my.cnf; 在配置文件的最后追加上:  代码如下 复制代码 query_cach...
  • zhaanghao
  • zhaanghao
  • 2015-03-06 09:49:57
  • 3636

【性能测试】自己遇到的常见问题

1
  • qi_lin7
  • qi_lin7
  • 2016-12-22 15:56:39
  • 748

mysql查询缓存优化

1,mysql查询缓存: 可以跳过sql的解析优化和查询等阶段,直接返回缓存结果给用户。 2,工作流程:    a,服务器接收sql,以sql和其它条件为key,查找缓存表(额外性能消耗)...
  • hxb147542579
  • hxb147542579
  • 2016-10-24 20:35:13
  • 240

Mybatis学习(十三)mybatis查询缓存理解

查询 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域...
  • sun_aichao
  • sun_aichao
  • 2015-06-11 11:46:50
  • 6459
收藏助手
不良信息举报
您举报文章:从遇到的一个性能问题学习mysql的查询缓存
举报原因:
原因补充:

(最多只允许输入30个字)