MySQL数据库,详解MySQL缓存机制

2021-04-20 11:04:21 浏览数 (1)

众所周知,缓存的设置是所有现代计算机系统发挥高性能的重要因素之一。对于MySQL数据库来说,也是得益于MySQL缓存机制,才能够提高MySQL数据库的性能,减少数据的内存占比。

MySQL缓存机制简单的说就是缓存SQL文本及查询结果,如果运行相同的SQL,服务器直接从缓存中取到结果,而不需要再去解析和执行SQL。如果表更改了,那么使用这个表的所有缓存查询将不再有效,查询缓存中值相关条目被清空。这里的更改指的是表中任何数据或是结构发生改变,包括INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE等,也包括那些映射到改变了的表使用MERGE表的查询。显然,这对于频繁更新的表,查询缓存是不适合的,而对于一些不常改变数据且有大量相同SQL查询的表,查询缓存会节约很大的性能。

一、MySQL缓存规则

1.开启了缓存,MySQL Server会自动将查询语句和结果集返回到内存,下次再查直接从内存中取;

2.缓存的结果是通过sessions共享的,所以一个client查询的缓存结果,另一个client也可以使用。

3.MySQL Query Cache内容为 select 的结果集, cache 使用完整的SQL字符串做 key, 并区分大小写,空格等。即两个SQL必须完全一致才会导致cache命中。即检查查询缓存时,MySQL Server不会对SQL做任何处理,它精确的使用客户端传来的查询,只要字符大小写或注释有点不同,查询缓存就认为是不同的查询;

4.prepared statement永远不会cache到结果,即使参数完全一样。在 5.1 之后会得到改善。

5.where条件中如包含任何一个不确定的函数将永远不会被cache, 比如current_date, now等。

6.date 之类的函数如果返回是以小时或天级别的,最好先算出来再传进去。

select * from foo where date1=current_date -- 不会被 cache

select * from foo where date1='2008-12-30' -- 被cache, 正确的做法

7.太大的result set不会被cache (< query_cache_limit)

8.MySQL缓存在分库分表环境下是不起作用的

9.执行SQL里有触发器,自定义函数时,MySQL缓存也是不起作用的

二、缓存失效

在表的结构或数据发生改变时,查询缓存中的数据不再有效。如INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE会导致缓存数据失效。所以查询缓存适合有大量相同查询的应用,不适合有大量数据更新的应用。

一旦表数据进行任何一行的修改,基于该表相关cache立即全部失效。

手动清理缓存

手动清理缓存可以使用下面三个SQL

1.FLUSH QUERY CACHE;#清理查询缓存内存碎片

2.RESET QUERY CACHE;#从查询缓存中移除所有查询

3.FLUSH TABLES;#关闭所有打开的表,同时该操作会清空查询缓存中的内容

四、缓存机制中的内存管理

MySQL Query Cache 使用内存池技术,自己管理内存释放和分配,而不是通过操作系统。内存池使用的基本单位是变长的block, 用来存储类型、大小、数据等信息;一个result set的cache通过链表把这些block串起来。block最短长度为query_cache_min_res_unit。

当服务器启动的时候,会初始化缓存需要的内存,是一个完整的空闲块。当查询结果需要缓存的时候,先从空闲块中申请一个数据块为参数query_cache_min_res_unit配置的空间,即使缓存数据很小,申请数据块也是这个,因为查询开始返回结果的时候就分配空间,此时无法预知结果多大。

分配内存块需要先锁住空间块,所以操作很慢,MySQL会尽量避免这个操作,选择尽可能小的内存块,如果不够,继续申请,如果存储完时有空余则释放多余的。

但是如果并发的操作,余下的需要回收的空间很小,小于query_cache_min_res_unit,不能再次被使用,就会产生碎片。

MySQL缓存机制从某种程度上来说,和其他的系统缓存有类似的作用:提高系统的性能,释放系统的内存空间。但MySQL缓存机制又有着其独特的特性,对于数据重复性比较高的查询有着显著的作用。

0 人点赞