标题: Query Cache Configuration

正文:

have_query_cache系统变量显示query_cache是否开启

1
2
3
4
5
6
mysql> SHOW VARIABLES LIKE 'have_query_cache';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| have_query_cache | YES |
+------------------+-------+

使用标准mysql二进制包安装时,默认为YES,即使query_cache是关闭的。

可以使用几个系统变量来控制query_cache。这些变量可以在配置文件里设置也可以在启动mysql时使用命令行指定。这些系统变量有个共同的特征,以querycache开头。这些变量在5.15节 系统变量一节有简单的描述。在这里会对这些配置详细介绍。

query_cache_size 会设置query_cache的大小。设置为0将关闭query_cache。默认是关闭的。如果你不打算使用query_cache,可以设置query_cache_type=0来显著减少系统开销。

注意
当我们使用windows安装程序安装mysql时,query_cache_size的默认值会基于不同的配置类型而改变。windows上默认是开启的。query_cache也会被query_cache_type控制。可以在my.ini文件中检查变量的值。

当你将query_cache_size设置为一个不为0的值时,记住query cache需要一个大概40kb的最小空间来分配它的架构。(具体大小与系统相关。)当你把最小值设置得较小时,会得到警告,就像下面这个例子一样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mysql> SET GLOBAL query_cache_size = 40000;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
Level: Warning
Code: 1282
Message: Query cache failed to set size 39936;
new query cache size is 0
mysql> SET GLOBAL query_cache_size = 41984;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW VARIABLES LIKE 'query_cache_size';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| query_cache_size | 41984 |
+------------------+-------+

想要缓存更多的查询结果,query cache的大小必须设置得再大一些:

1
2
3
4
5
6
7
8
9
10
mysql> SET GLOBAL query_cache_size = 1000000;
Query OK, 0 rows affected (0.04 sec)
mysql> SHOW VARIABLES LIKE 'query_cache_size';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| query_cache_size | 999424 |
+------------------+--------+
1 row in set (0.00 sec)

query_cache_size的值会占据1024byte空间。所以显示的值会比你设置得小一些。

如果query_cache_size大于0,query_cache_type变量会影响query cache的工作方式。此变量可以设置为以下值:

  • 0或者OFF 防止缓存和获取缓存结果
  • 1或者ON 开启缓存除非在语句中指定 SELECT SQL_NO_CACHE
  • 2或者DEMAND 只有指定SELECT SQL_CACHE才会使用缓存

如果query_cache_size为0,你还需要将query_cache_type设置为0。这种情况下,服务器根本不会去获得查询缓存互斥(query cache mutex),不能在服务器运行时开启query cache,并且也不能减少查询执行的系统开销。

设置GLOBAL query_cache_type 决定了所有的客户端的query cache行为。个别的客户端可以通过SESSION query_cache_type来通知query cache的行为。例如,一个客户端可以通过以下查询来关闭query cache:

1
mysql> SET SESSION query_cache_type = OFF;

如果在服务器启动时设置query_cache_type(而不是在运行时通过 SET 语句),那么只允许使用数字的值。

query_cache_limit系统变量可以控制个别查询结果大小的最大值。默认值为1MB。

当心,别将容量设置太大。因为在更新时,需要锁定cache。较大的缓存你会看到锁竞争的问题。

注意
你可以在运行时指定query cache的最大值,通过使用SET 语句 设置–maximum-query_cache_size=32M选项,可在命令行和配置文件中配置。

当一个query将要被缓存时,它的结果(被发送到客户端的数据)在结果获取期间被存储在query cache中。因此数据通常不在一个大块中处理。缓存一经请求,立刻为存储数据申请一块内存,当这块内存被填满时,就会再申请一块新内存。因为内存申请操作是想当昂贵的(时间方面来说),query cache会根据query_cache_min_res_unit系统变量的值申请内存。当一个查询被执行时,最后一个结果内存块会被截取成实际占用的大小,没有用到的内存就会被释放掉。根据服务器执行的查询类型,你会发现调整query_cache_min_res_unit的值很有用:

  • query_cache_min_res_unit默认值为4kb。大部分情况下够用。
  • 如果很多查询会产生小结果集会导致内存碎片的产生,这是因为提前申请了大的空闲内存块。由于缺少内存,内存碎片会强制清除缓存的查询。这种情况就要减少query_cache_min_res_unit的值。在清除缓存时,清除的内存空间和查询语句的数量取决于Qcache_free_blocks和Qcache_lowmem_prunes变量。
  • 如果说你的结果集都很大(查看一下 Qcache_total_blocks和 Qcache_queries_in_cache的值),你可以增加 query_cache_min_res_unit来提高性能。但是,千万别增加得太大了(上一条说明了太大会产生内存碎片)

相关文档

SET statement 文档地址