高性能MySQL之缓存
- 2019 年 11 月 11 日
- 筆記
10
Nov,2019
双十一仔细想了想,好像也没什么可买的,吃的零食什么的都还有,用的东西没什么缺的,想想还是算了吧,还不如早点搞完早点休息来的实在。个人感觉已经过了冲动消费的年纪了,这可能也是人老了的标志吧。。。

高性能MySQL之缓存
MySQL中的缓存是用来避免所查询的数据需要对磁盘进行访问,我们知道,磁盘上的访问会比内存的访问速度慢得多,所以,如果你的服务器上之部署了一个MySQL的服务,那么为它配置一个大的缓存无疑是明智之举。
在MySQL中,常用的缓存类型包含以下几种:
1、Innodb缓冲池
2、Innodb日志文件和MyISAM数据的操作系统缓存
3、MyISAM键缓存
4、查询缓存
今天我们简单介绍其中的1、2、4三类。
如果我们的MySQL服务器之设置了MyISAM一种存储引擎,那么我们完全可以关闭Innodb的各种配置,如果只使用了innodb存储引擎,则需要配置一部分MyISAM的内存资源,因为系统表中有些是使用的是MyISAM。如果大部分都是Innodb表,那么innodb缓冲池的大小就基本上决定了我们MySQL数据库的性能,我们知道,innodb缓冲池中并不仅仅缓存索引,还包含插入缓冲、锁信息等其他数据结构,innodb存储引擎是严重依赖缓冲池的。
如果数据量不大,而且不会快速增长,那么一个小的缓冲池其实也可以接受,也建议这么做。因为大的缓冲池除了会带来性能上的提升之外,还会带来一些问题。例如,数据的预热和实例的关闭都会花费很长时间,如果有很多"脏页"在缓冲池中,那么实例关闭的时候需要将这些脏页刷新回磁盘,就会导致实例的关闭时间比较长。当然,你会说,innodb可以强制关闭,这样是临时解决了关闭上的问题,但是当实例重启的时候,又会花费很多的时间进行恢复。我们可以在关闭实例之前,通过修改参数innodb_max_dirty_pages_pct的方法来讲脏页所占的百分比来减小,这样可以加速接下来的关闭过程。
当我们的存储引擎是MyISAM的时候,key_buffer_size这个参数就显得很重要了,这个参数代表的是键缓冲,如果MyISAM的表比较多,那么这个值应该设置的比较大,当然,也不是无限大,一般来讲,这个值最大不超过当前MyISAM索引所占的大小。默认情况下,MyISAM将所有的索引都缓存在默认的键缓存中,当然,这个值我们可以在配置文件中手动设置。最后,也是重要的一点,MyISAM中,索引是缓存在建缓存中的,而数据文件是缓存在操作系统的缓存中的,查询语句中索引的命中和数据的命中二者是不相关的。
MySQL在解析一个查询之前,如果查询缓存是打开的,则会首先在查询缓存中去查找是否命中缓存,当发现查询命中缓存之后,会检查一遍权限(注意,此时该查询语句并没有被解析,不用生成执行计划,不用被执行),如果权限没问题,那么MySQL将会跳过所有的阶段,直接从缓存中拿到结果并返回给客户端。在MySQL中,用于查询缓存的内存被分成了一个个的数据块,这些数据块中存储了自己的类型,大小和存储的数据本身,除了这些数据块之外,还有一个元数据维护的数据结构,当有查询结果需要缓存的时候,MySQL先从大的空间中申请一个数据块用于存储数据结果,这个数据块的大小是由参数query_cache_min_res_unit决定的,到这里,我们知道MySQL无法为每一个查询的结果精确分配恰好匹配的缓存空间。随着并发查询的进行,在查询缓存中也会出现内存碎片。
当然,我们可以根据实际情况来设置参数query_cache_min_res_unit的值,如果这个值query_cache_min_res_unit设置的很小,理论上浪费的空间就比较小,但是内存块的申请操作会变得比较频繁,影响数据库的性能,如果这个值设置的很大,那么查询缓存中的内存碎片会增多。
我们知道,查询缓存是为了提高查询的性能,但是如果你的查询每次都不一样,查询缓存的命中率过低,那么查询缓存有可能没有起到正向的效果,所以,查询缓存不一定会提高查询的效率,只有在查询缓存带来的资源节约大于其本身的资源小韩的时候,才会给系统带来性能提升。最后,我们介绍几个查询缓存的参数:
query_cache_type,这个参数控制是否打开查询缓存,可以设置为on、off或者demand,demand是指需要手工显示指定sql_cache的语句才放入查询缓存。
query_cache_size:这个参数是指查询缓存使用的总内存空间,单位是字节,一般MySQL会将其设置为1024的倍数。
query_cache_min_res_unit,这个参数上面说过了。
query_cache_limit,这个参数是指能够缓存的最大查询结果,如果查询结果大于这个值,则不会被缓存。
query_cache_wlock_invalidate,如果某个数据表被其他的连接锁住,是否仍然需要从查询缓存中返回结果,默认值是off,意思是数据库将返回其他线程锁住的数据,如果设置为on,则不会从缓存中返回这类数据,会等待锁的释放。

—END—
