php mysql 查询缓存_MySQL——查询缓存

说到缓存,大家应该都不陌生,从静态页面缓存到服务端动态缓存,再到数据库级别缓存等等。因为内存的读写速度比磁盘快若干倍,所以缓存是比较常用的提高性能的方式。

MySQL也有自己的缓存机制,可以针对sql进行缓存。比如我们发送select * from my_tb这么一个查询,MySQL首先检索内存中是否有数据并且数据是否过期,如果没有数据或者数据已经过期就去数据库中查找,如果有数据并且没有过期就直接返回数据。对于sql的匹配规则非常简单,就是字符串的比较,只要字符串相同,那么就认为是同一个查询。这里的字符串相同并不是表示sql语义相同,而是查询的sql字符串相同,空格也不行。MySQL的缓存是对全部的sql有效的, 也就是说一旦开启了查询缓存,那么对所有的sql查询默认都是开启的。

可以通过下面的SQL查看当前查询缓存相关参数状态:

SHOW VARIABLES LIKE '%query_cache%';

输出结果类似下面:

query_cache_type

查询缓存类型,有0、1、2三个取值。0则不使用查询缓存。1表示始终使用查询缓存。2表示按需使用查询缓存。

如果query_cache_type为1而又不想利用查询缓存中的数据,可以用下面的SQL:

SELECT SQL_NO_CACHE * FROM ···

如果值为2,要使用缓存的话,需要使用SQL_CACHE开关参数:

SELECT SQL_CACHE * FROM ···

query_cache_size

默认情况下query_cache_size为0,表示为查询缓存预留的内存为0,则无法使用查询缓存。所以我们需要设置query_cache_size的值:

SET GLOBAL query_cache_size = 134217728;

注意上面的值如果设得太小不会生效。比如我用下面的SQL设置query_cache_size大小:

SET GLOBAL query_cache_size = 4000;

SHOW WARNINGS;

会返回下面的结果:

缓存条件

查询缓存可以看做是SQL文本和查询结果的映射。如果第二次查询的SQL和第一次查询的SQL完全相同(注意必须是完全相同,即使多一个空格或者大小写不同都认为不同)且开启了查询缓存,那么第二次查询就直接从查询缓存中取结果,可以通过下面的SQL来查看缓存命中次数(是个累加值):

SHOW STATUS LIKE 'Qcache_hits';

另外即使完全相同的SQL,如果使用不同的字符集、不同的协议等也会被认为是不同的查询而分别进行缓存。

不会缓存结果可能的情况:

1.当查询语句中有一些不确定的数据时,则不会被缓存。如包含函数NOW(),CURRENT_DATE()等类似的函数,或者用户自定义的函数,存储函数,用户变量等都不会被缓存。

2.当查询的结果大于query_cache_limit设置的值时,结果不会被缓存。

3.对于InnoDB引擎来说,当一个语句在事务中修改了某个表,那么在这个事务提交之前,所有与这个表相关的查询都无法被缓存。因此长时间执行事务,会大大降低缓存命中率。

4.查询语句中使用了LOCK  IN SHARE MODE、FOR UPDATE的语句,以及事务隔离级别为:Serializable情况下,所有查询语句都不能缓存。

5.对临时表的查询操作。

6.存在警告信息的查询语句。

7.之前缓存了查询结果,但是由于查询缓存内存不足,MySQL将某些缓存逐出,导致未命中。

8.缓存失效操作太多。数据修改,内存不足,缓存碎片都会导致缓存失效。

缓存数据失效时机

在表的结构或数据发生改变时,查询缓存中的数据不再有效。有这些INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE会导致缓存数据失效。所以查询缓存适合有大量相同查询的应用,不适合有大量数据更新的应用。

查询缓存带来的额外消耗:

1.在查询之前必须先检查是否命中缓存。

2.如果这个查询可以被缓存,那么执行完成后,MySQL发现查询缓存中没有这个查询,则会将结果存入查询缓存,这会带来额外的系统消耗。

3.写入或更新数据时,MySQL必须将对应表的所有缓存都设置失效。如果查询缓存很大或者碎片很多时,这个操作可能带来很大的系统消耗。

但这些开销相对来说较小,所以查询缓存对于查询多于写操作的情况还是很有好处的。

碎片如何产生:

假设查询的结果非常小,服务器在并发的向两个链接返回结果,这是在向A和B两个内存块写入数据,返回完结果后回收剩余的空间时,A剩余的空间小于query_cache_min_res_unit设置的值,这样就不能再次被查询缓存使用,从而产生了碎片,B剩余的空间则会释放,并入空闲内存部分。

可以使用下面三个SQL来清理查询缓存:

1、FLUSH QUERY CACHE; // 清理查询缓存内存碎片。

2、RESET QUERY CACHE; // 从查询缓存中移出所有查询。

3、FLUSH TABLES; //关闭所有打开的表,同时该操作将会清空查询缓存中的内容。

不懂的留言,每天一篇分享,玩转我们共同的爱好!

你也来投搞!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值