使用MYSQL查询缓存

回复 收藏
使用 Mysql 的查询缓存MySQL 的查询缓存是将客户端执行的 SELECT 语句和查询结构都缓存起来,如果再执行一个相同的查询,则不再进行解析和查询,直接将缓存的结果返回。这样的特性对于更新不频繁,以读操作为主的数据库有很大的性能提升。对于更新频繁的数据库则相对没有那么有效,因为数据的更新会将查询从查询缓存条目清空。
首先我们需要确认当前的数据库环境是否可以使用查询缓存特性,检查参数 have_query_cache :
mysql> show variables like 'have_query_cache';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| have_query_cache | YES |
+------------------+-------+
1 row in set (0.00 sec)
然后我们再查看当前的查询缓存的参数设置情况:
mysql> show variables like 'query_cache%';
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 0 |
| query_cache_type | ON |
| query_cache_wlock_invalidate | OFF |
+------------------------------+---------+
5 rows in set (0.00 sec)
query_cache_size 为查询缓存的大小,默认值为 0 ,表示禁用查询缓存。如果需要启用查询缓存,则需要修改这个参数的值。需要注意的是,由于查询缓存本身需要 40K 左右来保存数据结构,所以如果设置这个参数,则这个参数的值不能小于 40K 。
query_cache_type 设置查询缓存的工作方式: 0 或者 OFF ,表示阻塞查询缓存; 1 或 ON 表示允许缓存,以 SELECT SQL_NO_CACHE 开始的查询语句除外。 2 或 DEMAND ,表示仅对以 SELECT SQL_CACHE 开始的那些查询语句启用缓存。可以根据需要设置该参数的值。
query_cache_limit 设置可以被缓存的具体查询结果的最大值,默认值是 1M ,结果超过该值则不缓存。
可以使用 FLUSH QUERY CACHE 或者 RESET QUERY CACHE 来维护查询缓存:
2 FLUSH QUERY CACHE 用来清理查询缓存碎片,以提高内存使用性能。该语句不会从缓存中移出任何查询。
2 RESET QUERY CACHE 语句从查询缓存中移出所有查询。 FLUSH TABLES 语句也执行同样的工作。
可以使用 SHOW STATUS 来监控查询缓存使用的情况:
mysql> show status like 'Qcache%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 90752 |
| Qcache_hits | 4 |
| Qcache_inserts | 2 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 1 |
| Qcache_queries_in_cache | 2 |
| Qcache_total_blocks | 7 |
+-------------------------+-------+
8 rows in set (0.00 sec)
Qcache_hits :表示从查询缓存中返回结果的次数。
Qcache_inserts :表示加入到查询缓存的次数。
如果加入查询缓存的次数很大,但是从查询缓存返回结果的次数很小,说明查询缓存的效果并不是很好,可能是 SQL 复用的不多,也可能是结果更新的很频繁不适于缓存。
Qcache_lowmem_prunes :表示由于内存不够而从缓存删除的查询数量。如果这个值比较大,说明查询缓存设置的可能偏小,也有可能是因此导致 Qcache_hits 不够理想。
Qcache_queries_in_cache :表示当前被缓存的查询的数量,一旦数据发生了变化,则查询会自动从缓存中清除,这个值也会减小。如果 Qcache_inserts 很大,但是 Qcache_lowmem_prunes 和 Qcache_queries_in_cache 都偏小,则可能是由于表变更频繁导致不能使用查询缓存。
Qcache_not_cached :表示没有被缓存的查询的数目,查询没有被缓存的原因可能是因为结果集超过参数的设置,或者查询的时候指定 SQL_NO_CACHE ,或者是按照 query_cache_type 设定的原则,不会被缓存。
2010-03-16 10:56 举报
已邀请:
0

阿铭 管理员

赞同来自:

缓存cache机制简单说就是缓存cachesql文本及查询结果。如果运行相同sql,服务器直接从缓存cache中取到结果而不需要再去解析和执行sql.如果表更改了,那么使用这个表所有缓冲查询将不再有效。查询缓存cache值相关条目被清空更改指是表中任何数据或是结果改变包括insert,update,delete,truncate,altertable,droptable或dropdatabase等,也包括那些映射到改变了表使用merge表查询,显然这对于频繁更新查询缓存擦车是不适合。而对于那些补偿改变数据且有大量sql查询表查询缓存,此时,cache会节约很大性能。
查询必须是完全相同(逐字节相同)才能被认为是相同,另外同样查询串由于其他原因可能认为是区别,例如同样的查询字符串有可能认为是不同的,如:使用不同的数据库、不同的协议版本或者不同的默认字符集的查询,被认为是不同查询并且分别进行缓存cache.
mysql的cache功能的key的生产原理是:根据select语句生成key,select结果生成value,即key=>value。所以select语句是区分大小写的,也区分空格的。两个select必须完完全全一致,才能够获取到相应的cache.生成cache之后,只要该select中涉及到的table有任何的数据变动(insert,update,delete操作),相关的所有cache都会被删除。因此只有数据很少变动的table,引入mysql 的cache才较有意义。

查看cache的设置
show variables like ‘%query_cache%’
字段说明
have_query_cache YES 查询cache是否可用
query_cache_limit 1048576 可缓存cache具体查询结果最大值
query_cache_min_res_unit 4096
query_cache_size 0 查询缓存cache大小;当query_cache_size默认为0时,是不开启cache功能的。设置大小取决于系统结构。
query_cache_type ON 阻止 或是支持查询缓存cache;0表示关闭QC;1表示正常缓存;2表示SQL_CACHE才缓存
query_cache_wlock_invalidate OFF

query_cache_size 说明
* 0或OFF将阻止缓存或查询缓存结果。
* 1或ON将允许缓存,以SELECT SQL_NO_CACHE开始的查询语句除外。
* 2或DEMAND,仅对以SELECT SQL_CACHE开始的那些查询语句启用缓存。

性能监控:
show status like ‘%Qcache%’

show status like ‘Qcache_hits’ Qcache_hits表示sql查询在缓存cache中命中累计次数是累加值。

配置query_cache_type,同时改写程序:
query_cache_type 0 代表不使用缓冲, 1 代表使用缓冲,2 代表根据需要使用。
设置 1 代表缓冲永远有效,如果不需要缓冲,就需要使用如下语句:
SELECT SQL_NO_CACHE * FROM my_table WHERE …
如果设置为 2 ,需要开启缓冲,可以用如下语句:
SELECT SQL_CACHE * FROM my_table WHERE …
So,只要把query_cache_type设置为2,然后在需要提高select速度的地方,使用:
SELECT SQL_CACHE * FROM…

mysql cache的清理:
可以使用FLUSH QUERY CACHE语句来清理查询缓存碎片以提高内存使用性能。该语句不从缓存中移出任何查询。
RESET QUERY CACHE语句从查询缓存中移出所有查询。FLUSH TABLES语句也执行同样的工作。

从只有一行的表中查找一行数据时,使用查询缓存比不使用速度快238%。

回复帖子,请先登录注册

退出全屏模式 全屏模式 回复
评分
可选评分理由: