文章目录

  • 查询缓存
  • 原理
  • 生产如何设置MySQL Query Cache



是使用mysql的缓存 mysql缓存原理_查询缓存

  • 1.当客户端连接到MySQL服务器时,服务器对其进行认证。可以通过用户名与密码认证,也可以通过SSL证书进行认证。登录认证后,服务器还会验证客户端是否有执行某个查询的操作权限。
  • 2.在正式查询之前,服务器会检查查询缓存,如果能找到对应的查询,则不必进行查询解析,优化,执行等过程,直接返回缓存中的结果集。
  • 3.MySQL的解析器会根据查询语句,构造出一个解析树,主要用于根据语法规则来验证语句是否正确,比如SQL的关键字是否正确,关键字的顺序是否正确。
    而预处理器主要是进一步校验,比如表名,字段名是否正确等
  • 4.查询优化器将解析树转化为查询计划,一般情况下,一条查询可以有很多种执行方式,最终返回相同的结果,优化器就是根据成本找到这其中最优的执行计划
  • 5.执行计划调用查询执行引擎,而查询引擎通过一系列API接口查询到数据
  • 6.得到数据之后,在返回给客户端的同时,会将数据存在查询缓存中

查询缓存

MariaDB [(none)]> show variables like '%query_cache%';
+------------------------------+---------+
| Variable_name                | Value   |
+------------------------------+---------+
| have_query_cache             | YES     |
| query_cache_limit            | 1048576 |
| query_cache_min_res_unit     | 4096    |
| query_cache_size             | 0       |
| query_cache_strip_comments   | OFF     |
| query_cache_type             | ON      |
| query_cache_wlock_invalidate | OFF     |
+------------------------------+---------+
7 rows in set (0.01 sec)
have_query_cache#当前的MYSQL版本是否支持“查询缓存”功能。

query_cache_limit#MySQL能够缓存的最大查询结果,查询结果大于该值时不会被缓存。默认值是1048576(1MB)

query_cache_min_res_unit#查询缓存分配的最小块(字节)。默认值是4096(4KB)。当查询进行时,MySQL把查询结果保存在query cache,但是如果保存的结果比较大,超过query_cache_min_res_unit的值,这时候MySQL将一边检索结果,一边进行保存结果。他保存结果也是按默认大小先分配一块空间,如果不够,又要申请新的空间给他。如果查询结果比较小,默认的query_cache_min_res_unit可能造成大量的内存碎片,如果查询结果比较大,默认的query_cache_min_res_unit又不够,导致一直分配块空间,所以可以根据实际需求,调节query_cache_min_res_unit的大小。

注:如果上面说的内容有点弯弯绕,那举个现实生活中的例子,比如咱现在要给运动员送水,默认的是500ml的瓶子,如果过来的是少年运动员,可能500ml太大了,他们喝不完,造成了浪费,那我们就可以选择300ml的瓶子,如果过来的是成年运动员,可能500ml不够,那他们一瓶喝完了,又开一瓶,直接不渴为止。那么那样开瓶子也要时间,我们就可以选择1000ml的瓶子。

query_cache_size#为缓存查询结果分配的总内存。
query_cache_type#默认为on,可以缓存除了以select sql_no_cache开头的所有查询结果。
query_cache_wlock_invalidate#如果该表被锁住,是否返回缓存中的数据,默认是关闭的。

原理

MYSQL的查询缓存实质上是缓存SQL的hash值和该SQL的查询结果,如果运行相同的SQL,服务器直接从缓存中去掉结果,而不再去解析,优化,寻找最低成本的执行计划等一系列操作,大大提升了查询速度。

但是万事有利也有弊。
第一个弊端就是如果表的数据有一条发生变化,那么缓存好的结果将全部不再有效。这对于频繁更新的表,查询缓存是不适合的。
比如一张表里面只有两个字段,分别是id和name,数据有一条为1,张三。我使用select * from 表名 where name=“张三”来进行查询,MySQL发现查询缓存中没有此数据,会进行一系列的解析,优化等操作进行数据的查询,查询结束之后将该SQL的hash和查询结果缓存起来,并将查询结果返回给客户端。但是这个时候我有新增了一条数据2,张三。如果我还用相同的SQL来执行,他会根据该SQL的hash值去查询缓存中,那么结果就错了。所以MySQL对于数据有变化的表来说,会直接清空关于该表的所有缓存。这样其实是效率是很差的。

第二个弊端就是缓存机制是通过对SQL的hash,得出的值为key,查询结果为value来存放的,那么就意味着SQL必须完完全全一模一样,否则就命不中缓存。
我们都知道hash值的规则,就算很小的查询,哈希出来的结果差距是很多的,所以select * from 表名 where name=“张三”和SELECT * FROM 表名 WHERE NAME=“张三”和select * from 表名 where name = “张三”,三个SQL哈希出来的值是不一样的,大小写和空格影响了他们,所以并不能命中缓存,但其实他们搜索结果是完全一样的。

生产如何设置MySQL Query Cache

是使用mysql的缓存 mysql缓存原理_缓存_02


我们发现将query_cache_type设置为OFF,其实网上资料和各大云厂商提供的云服务器都是将这个功能关闭的,从上面的原理来看,在一般情况下,他的弊端大于优点。