博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
超易懂的MySQL缓存机制
阅读量:3962 次
发布时间:2019-05-24

本文共 2525 字,大约阅读时间需要 8 分钟。

文章目录

在这里插入图片描述

  • 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

在这里插入图片描述

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

转载地址:http://jqezi.baihongyu.com/

你可能感兴趣的文章
活动图(Activity Diagram)—UML图(四)
查看>>
C#方法重载(overload)方法重写(override)隐藏(new)
查看>>
CSS+DIV练手-公司
查看>>
CSS+DIV练手—鲜花展
查看>>
深入浅出JavaScript(1)—ECMAScript
查看>>
深入浅出JavaScript(2)—ECMAScript
查看>>
Asp.Net+Jquery.Ajax详解1-开篇
查看>>
我的软件工程之路(四)—半年总结
查看>>
Asp.Net+Jquery.Ajax详解5-$.getScript
查看>>
Asp.Net+Jquery.Ajax详解6-$.ajaxSetup
查看>>
什么是Dojo?与Jquery宏观对比,结果如何?
查看>>
Asp.Net+Jquery.Ajax详解8-核心$.ajax
查看>>
项目中一个用于导出word的方法
查看>>
测试Jsp 静态包含和动态包含
查看>>
简析几种常用的Web监听
查看>>
Web应用过滤器Fileter
查看>>
代理模式(Proxy)
查看>>
采用动态代理对事务进行封装
查看>>
Hibernate性能优化
查看>>
Spring核心ioc
查看>>