机器的内存越来越大,人们也都习惯性的把以前有用的参数分配的值越来越大。这个参数加大后也引发了一系列问题。我们首先分析一下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)