Mysql性能优化案例研究-覆盖索引和SQL_NO_CACHE

2019-01-04 16:27:03于海丽

当我们想用SQL_NO_CACHE来禁止结果缓存时发现结果和我们的预期不一样,查询执行的结果仍然是缓存后的结果。其实,SQL_NO_CACHE的真正作用是禁止缓存查询结果,但并不意味着cache不作为结果返回给query。

在说白点就是,不是本次查询不使用缓存,而是本次查询结果不做为下次查询的缓存。

还有就是,mysql本身是有对sql语句缓存的机制的,合理设置我们的mysql缓存可以降低数据库的io资源,因此,这里我们有必要再看一下如何控制这个比较安逸的功能。

看图如下:

其中各项的含义为:

1、have_query_cache
是否支持查询缓存区 “YES”表是支持查询缓存区

2、query_cache_limit
可缓存的Select查询结果的最大值 1048576 byte /1024 = 1024kB 即最大可缓存的select查询结果必须小于 1024KB

3、query_cache_min_res_unit
每次给query cache结果分配内存的大小 默认是 4096 byte 也即 4kB

4、query_cache_size
如果你希望禁用查询缓存,设置 query_cache_size=0。禁用了查询缓存,将没有明显的开销

5、query_cache_type
查询缓存的方式(默认是 ON)

1、完整查询的过程如下

当查询进行的时候,Mysql把查询结果保存在qurey cache中,但是有时候要保存的结果比较大,超过了query_cache_min_res_unit的值 ,这时候mysql将一边检索结果,一边进行慢慢保存结果,所以,有时候并不是把所有结果全部得到后再进行一次性保存,而是每次分配一块query_cache_min_res_unit 大小的内存空间保存结果集,使用完后,接着再分配一个这样的块,如果还不不够,接着再分配一个块,依此类推,也就是说,有可能在一次查询中,mysql要进行多次内存分配的操作,而我们应该知道,频繁操作内存都是要耗费时间的。

2、内存碎片的产生

当一块分配的内存没有完全使用时,MySQL会把这块内存Trim掉,把没有使用的那部分归还以重复利用。比如,第一次分配4KB,只用了3KB,剩1KB,第二次连续操作,分配4KB,用了2KB,剩2KB,这两次连续操作共剩下的1KB+2KB=3KB,不足以做个一个内存单元分配,这时候,内存碎片便产生了。

3.内存块的概念

先看下这个:

Qcache_total_blocks 表示所有的块

Qcache_free_blocks 表示未使用的块
这个值比较大,那意味着,内存碎片比较多,用flush query cache清理后,为被使用的块其值应该为1或0 ,因为这时候所有的内存都做为一个连续的快在一起了.

Qcache_free_memory 表示查询缓存区现在还有多少的可用内存
Qcache_hits 表示查询缓存区的命中个数,也就是直接从查询缓存区作出响应处理的查询个数