MySQL Query Cache

    对于使用MySQL的用户,对于这个变量大家一定不会陌生。前几年的MyISAM引擎优化中,这个参数也是一个重要的优化参数。但随着发展,这个参数也爆露出来一些问题。

    机器的内存越来越大,人们也都习惯性的把以前有用的参数分配的值越来越大。这个参数加大后也引发了一系列问题。我们首先分析一下query_cache_size的工作原理:

    一个SELECT查询在DB中工作后,DB会把该语句缓存下来,当同样的一个SQL再次来到DB里调用时,DB在该表没发生变化的情况下把结果从缓存中返回给Client。

    这里有一个关建点,就是DB在利用Query_cache工作时,要求该语句涉及的表在这段时间内没有发生变更(表有一点的変更也不行,包括INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE, or DROP DATABASE等)。那如果该表在发生变更时,Query_cache里的数据又怎么处理呢?首先要把Query_cache和该表相关的语句全部置为失效,然后在写入更新。那么如果Query_cache非常大,该表的查询结构又比较多,查询语句失效也慢,一个更新或是Insert就会很慢,这样看到的就是Update或是Insert怎么这么慢了。

    所以在数据库写入量或是更新量也比较大的系统,该参数不适合分配过大。而且在高并发,写入量大的系统,建系把该功能禁掉(可能会引起严重的Waiting for query cache lock)。

关闭QC的方法

query_cache_type = off

query_cache_size = 0

说明:(1)、想要彻底关闭query cache,务必在一开始就设置 query_cache_type = 0,即便是启动后将 query_cache_type 从 1 改成 0,也不行;

            (2)、即便query_cache_size = 0,但 query_cache_type 非 0 的话,在实际环境中,可能会频繁发生 Waiting for query cache lock;

            (3)、一开始就设置 query_cache_type = 0 的话,没有办法在运行过程中再次动态启用,反过来则可以。也就是说,一开始是启用 query cache 的, 在运行过程中将其关闭,但事实上仍然会发生  Waiting for query cache lock,并没有真正的关闭

QC原理图

QC相关参数
    query_cache_size QC占用空间大小,通过将其设置为0关闭QC功能
    query_cache_type 0表示关闭QC;1表示正常缓存,除非用SQL_NO_CACHE才不缓存(默认值)  2表示SQL_CACHE才缓存
    query_cache_limit 最大缓存结果集大小(默认1M)
    query_cache_min_res_unit 手册上说,QC会按照这个值分配缓存block的大小(默认4K)。
    Qcache_lowmem_prunes 这是一个状态变量(show status),当缓存空间不够需要释放旧的缓存时,该值会自增。表示从QC中删除的查询。

说明:上面的参数官方文档说明的很清楚。

缓存失效示例

[root@slave159 mysql-5.5.41]# /etc/init.d/mysql3307 restart;mysql -uroot -P3307 -h 192.168.60.159 huang


mysql> CREATE TABLE t(id INT,var1 varchar(10));
Query OK, 0 rows affected (0.43 sec)

mysql> show  status like 'Com_select'\G show  status like 'Qcache_hits'\G  show  status like 'Qcache_queries_in_cache'\G
*************************** 1. row ***************************
Variable_name: Com_select
        Value: 1
1 row in set (0.01 sec)

*************************** 1. row ***************************
Variable_name: Qcache_hits
        Value: 0
1 row in set (0.00 sec)

*************************** 1. row ***************************
Variable_name: Qcache_queries_in_cache
        Value: 0
1 row in set (0.00 sec)


mysql> INSERT INTO t VALUES(1,'WWW');
Query OK, 1 row affected (0.02 sec)

mysql> show  status like 'Com_select'\G show  status like 'Qcache_hits'\G  show  status like 'Qcache_queries_in_cache'\G
*************************** 1. row ***************************
Variable_name: Com_select
        Value: 1
1 row in set (0.00 sec)

*************************** 1. row ***************************
Variable_name: Qcache_hits
        Value: 0
1 row in set (0.01 sec)

*************************** 1. row ***************************
Variable_name: Qcache_queries_in_cache
        Value: 0
1 row in set (0.00 sec)

mysql> SELECT * FROM t WHERE id=1;       
+------+------+
| id   | var1 |
+------+------+
|    1 | WWW  |
+------+------+
1 row in set (0.00 sec)

mysql> show  status like 'Com_select'\G show  status like 'Qcache_hits'\G  show  status like 'Qcache_queries_in_cache'\G
*************************** 1. row ***************************
Variable_name: Com_select
        Value: 2
1 row in set (0.00 sec)

*************************** 1. row ***************************
Variable_name: Qcache_hits
        Value: 0
1 row in set (0.00 sec)

*************************** 1. row ***************************
Variable_name: Qcache_queries_in_cache                           -- 从这个参数看出上面的SQL被缓存了
        Value: 1
1 row in set (0.00 sec)



mysql> SELECT * FROM t WHERE id=1;
+------+------+
| id   | var1 |
+------+------+
|    1 | WWW  |
+------+------+
1 row in set (0.00 sec)


mysql> show  status like 'Com_select'\G show  status like 'Qcache_hits'\G  show  status like 'Qcache_queries_in_cache'\G
*************************** 1. row ***************************
Variable_name: Com_select
        Value: 2
1 row in set (0.01 sec)

*************************** 1. row ***************************
Variable_name: Qcache_hits
        Value: 1                                                  -- 从这个参数看出上面的SQL缓存命中了
1 row in set (0.00 sec)

*************************** 1. row ***************************
Variable_name: Qcache_queries_in_cache
        Value: 1
1 row in set (0.00 sec)


mysql> INSERT INTO t VALUES(2,'RRRR');
Query OK, 1 row affected (0.03 sec)

mysql> show  status like 'Com_select'\G show  status like 'Qcache_hits'\G  show  status like 'Qcache_queries_in_cache'\G
*************************** 1. row ***************************
Variable_name: Com_select
        Value: 2
1 row in set (0.00 sec)

*************************** 1. row ***************************
Variable_name: Qcache_hits
        Value: 1
1 row in set (0.00 sec)

*************************** 1. row ***************************
Variable_name: Qcache_queries_in_cache
        Value: 0                                                   -- 从这个参数看出上面的SQL使得之前的SQL缓存失效了
1 row in set (0.00 sec)


mysql> SELECT * FROM t WHERE id=1;
+------+------+
| id   | var1 |
+------+------+
|    1 | WWW  |
+------+------+
1 row in set (0.00 sec)

mysql> show  status like 'Com_select'\G show  status like 'Qcache_hits'\G  show  status like 'Qcache_queries_in_cache'\G
*************************** 1. row ***************************
Variable_name: Com_select
        Value: 3
1 row in set (0.00 sec)

*************************** 1. row ***************************
Variable_name: Qcache_hits
        Value: 1                                                   -- 从这个参数看出上面的SQL缓存没有命中(也印证了上一个SQL缓存失效)
1 row in set (0.01 sec)

*************************** 1. row ***************************
Variable_name: Qcache_queries_in_cache
        Value: 1                                                   -- 从这个参数看出这个SQL被缓存了
1 row in set (0.00 sec)
	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值