011-MySQL Query Cache 查询缓存设置操作

一、概述

  MySQL Query Cache 会缓存select 查询,安装时默认是开启的,但是如果对表进行INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE, or DROP DATABASE等操作时,之前的缓存会无效并且删除。这样一定程度上也会影响我们数据库的性能。所以对一些频繁的变动表的情况开启缓存是不明智的。还有一种情况我们测试数据库性能的时候也要关闭缓存,避免缓存对我们测试数据的影响。

1.1、QueryCache的实现原理;

  1、目前只有select语句会被cache,其他类似show,use的语句则不会被cache。

  2、两个SQL语句,只要相差哪怕是一个字符(例如大小写不一样;多一个空格等),那么这两个SQL将使用不同的一个CACHE。

  但是会:

  • 过滤所有注释
  • 去掉SQL文本前後的空格,TAB等字符。注意,是文本前面和後面的。中间的不会被去掉。

  一个被频繁更新的表如果被应用了QC,可能会加重数据库的负担,而不是减轻负担。一般的做法是默认打开QC,而对一些涉及频繁更新的表的SQL语句加上SQL_NO_CACHE关键词来对其禁用CACHE。这样可以尽可能避免不必要的内存操作,尽可能保持内存的连续性。那些查询很分散的SQL语句,也不应该使用QC。例如用来查询用户和密码的语句——“select pass from user where name='surfchen'”。这样的语句,在一个系统里,很有可能只在一个用户登陆的时候被使用。每个用户的登陆所用到的查询,都是不一样的SQL文本,QC在这里就几乎不起作用了,因为缓存的数据几乎是不会被用到的,它们只会在内存里占地方。

1.2、QueryCache的负面影响:

    1,Query的hash性能问题和命中率问题;
    2,查询缓存及其容易失效;当表内容发生变化或者表结构发生变化,对应的查询缓存内容都会失效;
    3,查询缓存中的结果容易产生重复;因为查询缓存中缓存的是查询结果,所以不同的查询的结果很容易重复;

1.3、Query Cache的使用:

    1,设置query_cache_limit为查询缓存大小,如果为0,则不使用查询缓存;
    2,使用SQL_CACHE或者SQL_NO_CACHE来强制是否使用查询缓存;

如, 如果query_cache_type为1而又不想利用查询缓存中的数据,可以用下面的SQL: 

SELECT SQL_NO_CACHE * FROM my_table WHERE condition;
    如果值为2,要使用缓存的话,需要使用SQL_CACHE开关参数:
SELECT SQL_CACHE * FROM my_table WHERE condition;

    3,查询查询缓存设置:show variables like '%query_cache%';
        1,“have_query_cache”:该MySQL 是否支持Query Cache;按实际情况YES 或 NO
        2,“query_cache_limit”:Query Cache 存放的单条Query 最大Result Set ,默认1M;
        3,“query_cache_min_res_unit”:Query Cache 每个Result Set 存放的最小内存大小,默认4k;
        4,“query_cache_size”:系统中用于Query Cache 内存的大小;默认为0,表示为查询缓存预留的内存为0,则无法使用查询缓存。所以我们需要设置query_cache_size的值: 
        5,“query_cache_type”:系统是否打开了Query Cache 功能;默认为OFF

   

开始关闭缓存。关闭缓存有两种放法,一种临时的,一种永久的。

  临时的直接再命令行执行

  set global query_cache_size=0

  set global query_cache_type=0

永久的修改配置文件my.cnf ,添加下面的配置即可。

  query_cache_type=0

  query_cache_size=0

1.4、 查询查询缓存使用情况:show status like 'Qcache%';

        1,“Qcache_free_blocks”:Query Cache 中目前还有多少剩余的blocks。如果该值显示较大,则说明Query Cache 中的内存碎片较多了
        2,“Qcache_free_memory”:Query Cache 中目前剩余的内存大小;
        3,“Qcache_hits”:多少次命中;
        4,“Qcache_inserts”:多少次未命中然后插入;Query Cache 命中率= Qcache_hits / ( Qcache_hits + Qcache_inserts );
        5,“Qcache_lowmem_prunes”:多少条Query 因为内存不足而被清除出Query Cache;
        6,“Qcache_not_cached”:因为query_cache_type 的设置或者不能被cache 的Query 的数量;
        7,“Qcache_queries_in_cache”:当前Query Cache 中cache 的Query 数量;
        8,“Qcache_total_blocks”:当前Query Cache 中的block 数量;

1.5、query cache的使用限制:

        1,mysql query cache内容为 select 的结果集, cache 使用完整的 sql 字符串做 key, 并区分大小写,空格等。即两个sql必须完全一致才会导致cache命中。
        2,prepared statement永远不会cache到结果,即使参数完全一样,
        3,where条件中如包含了某些函数永远不会被cache, 比如current_date, now等。
        4,太大的result set不会被cache (< query_cache_limit) 

1.6、query cache的使用方式:

        1,如果没有绝对的使用把握,可以关闭查询缓存;【其实按照默认配置即可,推荐由DBA统一运维】
        2,如果要使用查询缓存,最好能够精确的控制那些表内容放到查询缓存,哪些表不用查询缓存; 

注:存储块block说明

  QC缓存一个查询结果的时候,一般情况下不是一次性地分配足够多的内存来缓存结果的。而是在查询结果获得的过程中,逐块存储。当一个存储块被填满之後,一个新的存储块将会被创建,并分配内存(allocate)。单个存储块的内存分配大小通过query_cache_min_res_unit参数控制,默认为4KB。最後一个存储块,如果不能被全部利用,那么没使用的内存将会被释放。如果被缓存的结果很大,那么会可能会导致分配内存操作太频繁,系统系能也随之下降;而如果被缓存的结果都很小,那么可能会导致内存碎片过多,这些碎片如果太小,就很有可能不能再被分配使用。

  除了查询结果需要存储块之外,每个SQL文本也需要一个存储块,而涉及到的表也需要一个存储块(表的存储块是所有线程共享的,每个表只需要一个存储块)。存储块总数量=查询结果数量*2+涉及的数据库表数量。也就是说,第一个缓存生成的时候,至少需要三个存储块:表信息存储块,SQL文本存储块,查询结果存储块。而第二个查询如果用的是同一个表,那么最少只需要两个存储块:SQL文本存储块,查询结果存储块。

  通过观察Qcache_queries_in_cache和Qcache_total_blocks可以知道平均每个缓存结果占用的存储块。

  它们的比例如果接近1:2,则说明当前的query_cache_min_res_unit参数已经足够大了。

  如果Qcache_total_blocks比Qcache_queries_in_cache多很多,则需要增加query_cache_min_res_unit的大小。

  Qcache_queries_in_cache*query_cache_min_res_unit(sql文本和表信息所在的block占用的内存很小,可以忽略)如果远远大于query_cache_size-Qcache_free_memory,那么可以尝试减小query_cache_min_res_unit的值。

1.7、排序缓冲

  当一个查询需要对结果进行排序的时候,MySQL会分配一定的内存用来排序。这个内存大小由sort_buffer_size来控制。记得,这个参数是针对每个查询的,而不是所有查询总共可分配的量。

  如果sort_buffer_size不够大,排序的结果将会被分段写入临时文件里。每次结束之後再把文件中的排序结果拿出来合并,进行再次排序,直到得出最後结果。sort_buffer_size越小,合并的次数就越多。合并次数可以通过状态变量Sort_merge_passes获得。理论上,Sort_merge_passes越小,排序越快。但是在实际应用中可能并非如此。sort_buffer_size如何设置需要根据实际运行环境来进行测试。如果实在不知道如何测试,那么就设到使Sort_merge_passes为0吧。

read_buffer_size read_rnd_buffer_size join_buffer_size thread_cache

1.8、字段类型推荐

这条语句可以根据当前表的内容来给出一个字段类型的推荐。

  select * from test_table_idx PROCEDURE ANALYSE(); 

上述参考自:http://blog.csdn.net/iris_xuting/article/details/50495928#t0

可以使用下面三个SQL来清理查询缓存: 
1、FLUSH QUERY CACHE; // 清理查询缓存内存碎片。
2、RESET QUERY CACHE; // 从查询缓存中移出所有查询。
3、FLUSH TABLES; //关闭所有打开的表,同时该操作将会清空查询缓存中的内容。

 

fsd 

原文地址:https://www.cnblogs.com/bjlhx/p/11951199.html