很多数据库都能缓存查询的执行计划,对于相同类型的sql可以跳过SQL解析和执行计划生成阶段。而MySQL还有另一种缓存类型:缓存完整的SELECT查询结果,也就是“查询缓存”。
MySQL查询缓存保存查询返回的完整结果。当查询命中该缓存,MySQL会立刻返回结果,跳过了解析、优化和执行阶段。
查询缓存系统会跟踪查询中涉及的每个表,如果表有任何更改,包括INSERT、UPDATE、DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE等,那么使用这个表的所有缓冲查询将失效。
并不是什么情况查询缓存都能提高系统性能。缓存和失效都会带来额外的消耗:
1,读查询开始前需要先检查是否命中缓存
2,若查询可以被缓存,那么查询结果将存入查询缓存
3,如果修改某个表的数据,会将所有该表的所有缓存都失效,而失效是靠全局锁操作保护的,所有需要做该操作的查询都需要等待这个锁,如果查询缓存很大,就会带来巨大的系统消耗,成为非常严重的问题瓶颈
所以,只有当缓存带来的效率提升大于本身的资源消耗时才意义。
在高并发环境,多核处理器下,很多时候应该默认关闭查询缓存,如果查询缓存作用很大的话,一般设置几十兆。
缓存未命中的原因:
1,SQL中包含NOW()或CURRENT_DATE()一类函数的查询不会被缓存
2,结果集太大而无法缓存(query_cache_limit 默认1M,单SQL结果集超过1M则不会被缓存)
3,之前缓存过,但由于缓存可用内存用完,将某些查询缓存移出
一,配置查询缓存(查询缓存默认禁用,需要手动添加)
#缓存大小
query_cache_size
#缓存类型
query_cache_type
query_cache_type各个值如下:
0或off完全关闭缓存
1或on开启默认缓存,默认缓存所有SQL,可以使用sql_no_cache指定不缓存的语句,
如不缓存select sql_no_cache * from db1 where id=1
2或demand开启默认不缓存,默认不缓存所有SQL,可以使用sql_cache指定缓存的语句,
如缓存select sql_cache name from db2 where id=1
例:
query_cache_size = 10M
query_cache_type =1
二、查询缓存
mysql> show variables like '%query_cache%';
+------------------------------------------+-------------+
| Variable_name | Value |
+------------------------------------------+-------------+
| have_query_cache | YES |
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 10485760 |
| query_cache_type | ON |
| query_cache_wlock_invalidate | OFF |
+------------------------------------------+-------------+
6 rows in set (0.00 sec)
have_query_cache 的值如果是yes表示开启缓存
Binlog_cache_size:默认大小是32768即32K
Max_binlog_cache_size: 默认值是18446744073709547520,这个值很大,够我们使用的了。此参数和binlog_cache_size相对应,代表binlog所能使用的cache最大使用大小。如果系统中事务过多,而此参数值设置有小,则会报错。
query_cache_limit:允许 Cache 的单条 Query 结果集的最大容量,默认是1MB,超过此参数设置的Query 结果集将不会被 Cache,如何看查Query 结果大小呢?我还没有找到很好的办法,目前只能先把结果保存为txt文件,然后看大小。
query_cache_min_res_unit:设置 Query Cache 中每次分配内存的最小空间大小,也就是每个 Query 的 Cache 最小占用的内存空间大小
query_cache_size:设置 Query Cache 所使用的内存大小,默认值为0,大小必须是1024的整数倍,如果不是整数倍,MySQL 会自动调整降低最小量以达到1024的倍数
query_cache_type:控制 Query Cache 功能的开关,可以设置为0(OFF),1(ON)和2(DEMAND)三种,意义分别如下:
0(OFF):关闭 Query Cache 功能,任何情况下都不会使用 Query Cache
1(ON):开启 Query Cache 功能,但是当 SELECT 语句中使用的 SQL_NO_CACHE 提示后,将不使用Query Cache
2(DEMAND):开启 Query Cache 功能,但是只有当 SELECT 语句中使用了 SQL_CACHE 提示后,才使用 Query Cache
query_cache_wlock_invalidate:控制当有写锁定发生在表上的时刻是否先失效该表相关的 Query Cache,如果设置为 1(TRUE),则在写锁定的同时将失效该表相关的所有 Query Cache,如果设置为0(FALSE)则在锁定时刻仍然允许读取该表相关的 Query Cache。
查询缓存状态
mysql> show status like 'qcache%';
+------------------------------------+--------------+
| Variable_name | Value |
+------------------------------------+--------------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 10475424 |
| Qcache_hits | 1 |
| Qcache_inserts | 1 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 0 |
| Qcache_queries_in_cache | 1 |
| Qcache_total_blocks | 4 |
+------------------------------------+--------------+
8 rows in set (0.00 sec)
Qcache_free_blocks:目前还处于空闲状态的 Query Cache中内存 Block数目,如果该值较多,表示内存碎片较多,需要清理,flush query cache
Qcache_free_memory:目前还处于空闲状态的 Query Cache内存总量
Qcache_hits:Query Cache命中次数,命中越高,说明利用率越高,如果命中低,代表数据经常更新或者查询频率低
Qcache_inserts:向 Query Cache中插入新的Query Cache的次数,也就是没有命中的次数
Qcache_lowmem_prunes:当 Query Cache内存容量不够,需要从中删除老的Query Cache以给新的 Cache 对象使用的次数,如果该值比较大,表示查询缓存区大小设置太小,需要增大。
Qcache_not_cached:没有被 Cache的SQL数,包括无法被 Cache的 SQL以及由于query_cache_type设置的不会被Cache的 SQL
Qcache_queries_in_cache:目前在 Query Cache中的SQL数量
Qcache_total_blocks:Query Cache中总的Block数量
三,清理查询缓存
1,清理缓存碎片
flush query cache
2,清空缓存
reset query cache