1.1 连接器1.1.1连接器的紧张职责
1、卖力与客户真个通信,是半双工模式,这就意味着某一固定时刻只能由客户端向做事器要求或者做事器向客户端发送数据,而不能同时进行,个中MySQL在与客户端连接TC/IP的。
2、验证要求用户的账户和密码是否精确,如果账户和密码缺点,会报错:Access denied for user 'root'@'localhost' (using password: YES)
3、如果用户的账户和密码验证通过,会在MySQL自带的权限表中查询当前用户的权限。

MySQL中存在4个掌握权限的表,分别为user表,db表,tables_priv表,columns_priv表:
user表:存放用户账户信息以及全局级别(所有数据库)权限,决定了来自哪些主机的哪些用户可以访问数据库实例db表:存放数据库级别的权限,决定了来自哪些主机的哪些用户可以访问此数据库tables_priv表:存放表级别的权限,决定了来自哪些主机的哪些用户可以访问数据库的这个表columns_priv表:存放列级别的权限,决定了来自哪些主机的哪些用户可以访问数据库表的这个字段1.1.2 MySQL权限表的验证过程1、 先从user表中的Host,User,Password这3个字段中止定连接的IP、用户名、密码是否存在,存在则通过验证。
2、通过身份认证后,进行权限分配,按照user,db,tables_priv,columns_priv的顺序进行验证。即先检讨全局权限表user,如果user中对应的权限为Y,则此用户对所有数据库的权限都为Y,将不再检讨db,tables_priv,columns_priv;如果为N,则到db表中检讨此用户对应的详细数据库,并得到db中为Y的权限;如果db中为N,则检讨tables_priv中此数据库对应的详细表,取得表中的权限Y,以此类推。
3、如果在任何一个过程中权限验证不通过,都会报错。
1.2 缓存MySQL的缓存紧张的浸染是为了提升查询的效率,缓存以key和value的哈希脸色势存储,key是详细的SQL语句,value是结果的凑集。如果无法命中缓存,就连续走到剖析器的这一步,如果命中缓存就直接返回给客户端。不过须要把稳的是在MySQL的8.0版本往后,缓存被官方删除掉了。之以是删除掉,是由于查询缓存的失落效非常频繁,如果在一个写多读少的环境中,缓存会频繁的新增和失落效。对付某些更新压力大的数据库来说,查询缓存的命中率会非常低,MySQL为了掩护缓存可能会涌现一定的伸缩性的问题,目前在5.6的版本中已经默认关闭了,比较推举的一种做法是将缓存放在客户端,性能大概会提升5倍旁边。
1.3 剖析器剖析器的紧张浸染是将客户端发过来的SQL语句进行剖析,这将包括预处理与解析过程,在这个阶段会解析SQL语句的语义,并进行关键词和非关键词进行提取、解析,并组成一个解析树。详细的关键词包括不限定于以下:
select/update/delete/or/in/where/group by/having/count/limit等。如果剖析到语法缺点,会直接给客户端抛出非常:ERROR:You have an error in your SQL syntax.。
比如:select from user where userId =1234;
在剖析器中就通过语义规则器将select from where这些关键词提取和匹配出来,MySQL会自动判断关键词和非关键词,将用户的匹配字段和自定义语句识别出来。这个阶段也会做一些校验:比如校验当前数据库是否存在user表,同时如果user表中不存在userId这个字段同样会报错:unknown column in field list.
1.4 优化器能够进入到优化器阶段表示SQL是符合MySQL的标准语义规则的并且可以实行的,此阶段紧张是进行SQL语句的优化,会根据实行操持进行最优的选择,匹合营适的索引,选择最佳的实行方案。比如一个范例的例子是这样的:
表T,对A、B、C列建立联合索引,在进行查询的时候,当SQL查询到的结果是:select xx where B=x and A=x and C=x,很多人会以为是用不到索引的,但实在会用到,虽然索引必须符合最左原则才能利用,但是实质上,优化器会自动将这条SQL优化为:where A=x and B=x and C=X,这种优化会为了底层能够匹配到索引,同时在这个阶段是自动按照实行操持进行预处理,MySQL司帐算各个实行方法的最佳韶光,终极确定一条实行的SQL交给末了的实行器。
1.5 实行器在实行器的阶段,此时会调用存储引擎的API,API会调用存储引擎,紧张有以下存储的引擎,不过常用的还是myisam和innodb:
引擎以前的名字叫做:表处理器(实在这个名字我以为更能表达它存在的意义)卖力对详细的数据文件进行操作,对SQL的语义比如select或者update进行剖析,实行详细的操作。在实行完往后会将详细的操作记录到binlog中,须要把稳的一点是:select不会记录到binlog中,只有update/delete/insert才会记录到binlog中。而update会采取两阶段提交的办法,记录都redolog中。
二、实行的状态可以通过命令:show full processlist,展示所有的处理进程,紧张包含了以下的状态,表示做事器处理客户真个状态,状态包含了从客户端发起要求到后台做事器处理的过程,包括加锁的过程、统计存储引擎的信息,排序数据、搜索中间表、发送数据等。席卷了所有的MySQL的所有状态,个中详细的含义如下图:
三、SQL的实行顺序
事实上,SQL并不是按照我们的书写顺序来从前今后、左往右依次实行的,它是按照固定的顺序解析的,紧张的浸染便是从上一个阶段的实行返回结果来供应给下一阶段利用,SQL在实行的过程中会有不同的临时中间表,一样平常是按照如下顺序:
例子:
select distinct s.id from T t join S s on t.id=s.id where t.name="Yrion" group by t.mobile having count()>2 order by s.create_time limit 5;
这里有几个须要把稳的地方:
1、SQL语句是从FROM开始实行的,而不是SELECT。MySQL在实行SQL查询语句的时,首先是将数据从硬盘加载到数据缓冲区中,以便对这些数据进行操作。
2、SELECT是在FROM和GROUP BY 之后实行的。这就导致了无法在WHERE中利用SELECT中设置字段的别名作为查询条件。
3、UNION是排在ORDER BY之前的。虽然数据库许可SQL语句对UNION段中的子查询或者派生表进行排序,但是这并不能解释在 UNION 操作过后仍保持排序后的顺序。
4、在MySQL中SQL的逻辑查询是根据上述进行查询,但MySQL可能并不完备会按照逻辑查询处理办法进行查询。MySQL有2个组件:1),剖析SQL语句的Parser;2)、优化器Optimizer;MySQL在实行查询之前,都会选择一条自认为最优的查询方案去实行,获取查询结果。一样平常情形下都能打算出最优的查询方案,但在某些情形下,MySQL给出的查询方案并不是很好的查询方案。
5、存在索引时,优化器优先利用索引的插叙条件,当索引为多个时,优化器会直接选择效率最高的索引去实行。
四、SQL语句where后条件实行先后顺序4.1 结论针对MySQL,其条件实行顺序是 从左往右,自上而下。针对Orcale,其条件实行顺序是从右往左,自下而上。4.2 MySQLMySQL where实行顺序是从左往右实行的,在数据量小的时候不用考虑,但数据量多的时候要考虑条件的先后顺序,此时应遵守一个原则:打消越多的条件放在第一个。
在用MySQL查询数据库的时候,连接了很多个过滤条件,创造非常慢。例如:
select… where p.languages_id=1 and t.type=1 and p.products_id in(472,474),,这样查询须要20多秒,虽然在各个字段上都建立了索引。用剖析Explain SQL一剖析,创造在第一次剖析过程中就返回了几万条数据:where d p.languages_id=1 ,然后再依次根据条件缩小范围。
然后轻微改变一下where字段的位置之后,速率就有了明显地提高:
where p.products_id in(472,474) and p.languages_id=1 and t.type=1,这样第一次的过滤条件是p.products_id in(472,474),它返回的结果只有不到10条,接下来还要根据其它的条件来过滤,自然在速率上有了较大的提升。经由实践创造,不要以为where中的字段顺序无所谓,可以随便放在哪,该当尽可能地第一次就过滤掉大部分无用的数据,只返回最小范围的数据。
大多时候MySQL会自动根据SQL语句做出优化,利用最优的SQL语句进行查询。有时候MySQL无法根据SQL语句做出最优的优化顺序,以是还是要我们自己预判断出哪种过滤是最优,毕竟自己才最懂自己的数据。
原文链接:https://mp.weixin.qq.com/s/DS4-ObUFeGsU2l6FvF0Pcw