Bootstrap

mysql查询缓存是否需要开启_生产要不要开启MySQL查询缓存

一、前言

在当今的各种系统中,缓存是对系统性能优化的重要手段。MySQL Query Cache(MySQL查询缓存)在MySQL Server中是默认打开的,但是网上各种资料以及有经验的DBA都建议生产环境中把MySQL Query Cache关闭。按道理,MySQL Server默认打开,是鼓励用户使用缓存,但是大拿们却建议关闭此功能,并且国内各个云厂商提供的MySQL云服务中默认都是关闭这个功能,这是为什么?他们在使用中遇到了什么坑?本文将会从以下几方面来详解MySQL Query Cache。

1.MySQL查询缓存是什么?

MySQL缓存规则是什么?

如何配置和缓存MySQL缓存

MySQL缓存的优缺点

生产要不要开启MySQL缓存

二、 MySQL查询缓存简介

MySQL查询缓存是MySQL中比较独特的一个缓存区域,用来缓存特定Query的整个结果集信息,且共享给所有客户端。为了提高完全相同的Query语句的响应速度,MySQL Server会对查询语句进行Hash计算后,把得到的hash值与Query查询的结果集对应存放在Query Cache中。当MySQL Server打开Query Cache之后,MySQL Server会对接收到的每一个SELECT 语句通过特定的Hash算法计算该Query的Hash值,然后通过该hashi值到Query Cache中去匹配。

如果没有匹配,将这个hash值存放在一个hash链表中,并将Query的结果集存放到cache中,存放hashi值链表的每个hash节点存放了相应Quey结果集在cache中的地址,以及该query所涉及到一些table相关信息;

如果通过hash值匹配到了一样的Query,则直接将cache中相应的Query结果集返回给客户端。

目前MySQL Query Cache只会cache select语句,其他类似show ,use的语句不会被cache MySQL 的每个Query Cache都是以SQL文本作为key来存储的,在应用Query Cache之前,SQL文本不会做任何处理。也就是说,两个SQL语句,只要相差哪怕一个字符(例如大小写不一样,多一个空格,多注释),那么这两个SQL将使用不同的Cache地址。如: 下面三条SQL将会被存储在三个不同的缓存里,虽然他们的结果都是一样的。select FROM people where name='surfchen'; select FROM people where /hey~/ name='surfchen'; SELECT * FROM people where name='surfchen';

三、MySQL缓存机制

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

查询必须是完全相同(逐字节相同)才能够被认为是相同的。另外,同样的查询字符串由于其它原因可能认为是不同的。使用不同的数据库、不同的协议版本或者不同 默认字符集的查询被认为是不同的查询并且分别进行缓存。

需要注意的是MySQL Query Cache 是对大小写敏感的,因为Query Cache 在内存中是以 HASH 结构来进行映射,HASH 算法基础就是组成 SQL 语句的字符,所以 任何SQL语句的改变重新cache.

3.1 缓存规则

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

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

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

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

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

date

;