精华内容
下载资源
问答
  • mysql执行顺序
    2021-07-02 15:39:13

    mysql执行过程以及顺序

    前言:mysql在我们的开发中基本每天都要面对的,作为开发中的数据的来源,mysql承担者存储数据和读写数据的职责。因为学习和了解mysql是至关重要的,那么当我们在客户端发起一个sql到出现详细的查询数据,这其中究竟经历了什么样的过程?mysql服务端是如何处理请求的,又是如何执行sql语句的?本篇博客将来探讨这个问题:

    本篇博客的目录

    一:mysql执行过程

    二:mysql执行过程中的状态

    三:mysql执行的顺序

    四:总结

     一:mysql执行过程

    mysql整体的执行过程如下图所示:

     1.1:连接器

    连接器的主要职责就是:

    ①负责与客户端的通信,是半双工模式,这就意味着某一固定时刻只能由客户端向服务器请求或者服务器向客户端发送数据,而不能同时进行,其中mysql在与客户端连接TC/IP的

    ②验证请求用户的账户和密码是否正确,如果账户和密码错误,会报错:Access denied for user 'root'@'localhost' (using password: YES)

    ③如果用户的账户和密码验证通过,会在mysql自带的权限表中查询当前用户的权限:

    mysql中存在4个控制权限的表,分别为user表,db表,tables_priv表,columns_priv表,mysql权限表的验证过程为:

    1:User表:存放用户账户信息以及全局级别(所有数据库)权限,决定了来自哪些主机的哪些用户可以访问数据库实例
      Db表:存放数据库级别的权限,决定了来自哪些主机的哪些用户可以访问此数据库 
     Tables_priv表:存放表级别的权限,决定了来自哪些主机的哪些用户可以访问数据库的这个表 
     Columns_priv表:存放列级别的权限,决定了来自哪些主机的哪些用户可以访问数据库表的这个字段 
      Procs_priv表:存放存储过程和函数级别的权限

    2:先从user表中的Host,User,Password这3个字段中判断连接的ip、用户名、密码是否存在,存在则通过验证。

    3:通过身份认证后,进行权限分配,按照user,db,tables_priv,columns_priv的顺序进行验证。即先检查全局权限表user,如果user中对应的权限为Y,则此用户对所有数据库的权限都为Y,将不再检查db, tables_priv,columns_priv;如果为N,则到db表中检查此用户对应的具体数据库,并得到db中为Y的权限;如果db中为N,则检查tables_priv中此数据库对应的具体表,取得表中的权限Y,以此类推

    4:如果在任何一个过程中权限验证不通过,都会报错

    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;

    3.1:from

    第一步就是选择出from关键词后面跟的表,这也是sql执行的第一步:表示要从数据库中执行哪张表。

    实例说明:在这个例子中就是首先从数据库中找到表T

    3.2:join on

    join是表示要关联的表,on是连接的条件。通过from和join on选择出需要执行的数据库表T和S,产生笛卡尔积,生成T和S合并的临时中间表Temp1。on:确定表的绑定关系,通过on产生临时中间表Temp2.

    实例说明:找到表S,生成临时中间表Temp1,然后找到表T的id和S的id相同的部分组成成表Temp2,Temp2里面包含着T和Sid相等的所有数据

    3.3:where

    where表示筛选,根据where后面的条件进行过滤,按照指定的字段的值(如果有and连接符会进行联合筛选)从临时中间表Temp2中筛选需要的数据,注意如果在此阶段找不到数据,会直接返回客户端,不会往下进行.这个过程会生成一个临时中间表Temp3。注意在where中不可以使用聚合函数,聚合函数主要是(min\max\count\sum等函数)

    实例说明:在temp2临时表集合中找到T表的name="Yrion"的数据,找到数据后会成临时中间表Temp3,temp3里包含name列为"Yrion"的所有表数据

    3.4:group by 

    group by是进行分组,对where条件过滤后的临时表Temp3按照固定的字段进行分组,产生临时中间表Temp4,这个过程只是数据的顺序发生改变,而数据总量不会变化,表中的数据以组的形式存在

    实例说明:在temp3表数据中对mobile进行分组,查找出mobile一样的数据,然后放到一起,产生temp4临时表。

    3.5:Having

    对临时中间表Temp4进行聚合,这里可以为count等计数,然后产生中间表Temp5,在此阶段可以使用select中的别名

    实例说明:在temp4临时表中找出条数大于2的数据,如果小于2直接被舍弃掉,然后生成临时中间表temp5

    3.6:select

    对分组聚合完的表挑选出需要查询的数据,如果为*会解析为所有数据,此时会产生中间表Temp6

    实例说明:在此阶段就是对temp5临时聚合表中S表中的id进行筛选产生Temp6,此时temp6就只包含有s表的id列数据,并且name="Yrion",通过mobile分组数量大于2的数据

    3.7:Distinct

    distinct对所有的数据进行去重,此时如果有min、max函数会执行字段函数计算,然后产生临时表Temp7

    实例说明:此阶段对temp5中的数据进行去重,引擎API会调用去重函数进行数据的过滤,最终只保留id第一次出现的那条数据,然后产生临时中间表temp7

    3.8:order by 

    会根据Temp7进行顺序排列或者逆序排列,然后插入临时中间表Temp8,这个过程比较耗费资源

    实例说明:这段会将所有temp7临时表中的数据按照创建时间(create_time)进行排序,这个过程也不会有列或者行损失

     3.9:limit

    limit对中间表Temp8进行分页,产生临时中间表Temp9,返回给客户端。

    实例说明:在temp7中排好序的数据,然后取前五条插入到Temp9这个临时表中,最终返回给客户端

    ps:实际上这个过程也并不是绝对这样的,中间mysql会有部分的优化以达到最佳的优化效果,比如在select筛选出找到的数据集

     四:总结

     本篇博客总结了mysql的执行过程,以及sql的执行顺序,理解这些有助于我们对sql语句进行优化,以及明白mysql中的sql语句从写出来到最终执行的轨迹,有助于我们对sql有比较深入和细致的理解,提高我们的数据库理解能力。同时,对于复杂sql的执行过程、编写都会有一定程度的意义。

    更多相关内容
  • Mysql执行过程与BufferPool缓存机制.png
  • MySQL在我们的开发中基本每天都要面对的,作为开发中的数据的来源,MySQL承担者存储数据和读写数据的职责。因为学习和了解MySQL是至关重要的,那么当我们在客户端发起一个SQL到出现详...

    ff7aa0d92eac95594949392e070b3bcf.png

    MySQL在我们的开发中基本每天都要面对的,作为开发中的数据的来源,MySQL承担者存储数据和读写数据的职责。因为学习和了解MySQL是至关重要的,那么当我们在客户端发起一个SQL到出现详细的查询数据,这其中究竟经历了什么样的过程?MySQL服务端是如何处理请求的,又是如何执行SQL语句的?本篇博客将来探讨这些问题。

    MySQL执行过程

    5a9a5df7065087250035349731e20278.png

    MySQL整体的执行过程如下图所示:

    689e183aa3825ea3ab1200bd5a3ce57c.png

    连接器

    连接器的主要职责就是:

    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表:存放列级别的权限,决定了来自哪些主机的哪些用户可以访问数据库表的这个字段

    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、如果在任何一个过程中权限验证不通过,都会报错。

    缓存

    MySQL的缓存主要的作用是为了提升查询的效率,缓存以key和value的哈希表形式存储,key是具体的SQL语句,value是结果的集合。如果无法命中缓存,就继续走到分析器的这一步,如果命中缓存就直接返回给客户端。不过需要注意的是在MySQL的8.0版本以后,缓存被官方删除掉了。之所以删除掉,是因为查询缓存的失效非常频繁,如果在一个写多读少的环境中,缓存会频繁的新增和失效。对于某些更新压力大的数据库来说,查询缓存的命中率会非常低,MySQL为了维护缓存可能会出现一定的伸缩性的问题,目前在5.6的版本中已经默认关闭了,比较推荐的一种做法是将缓存放在客户端,性能大概会提升5倍左右。

    分析器

    分析器的主要作用是将客户端发过来的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.”。

    优化器

    能够进入到优化器阶段表示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交给最后的执行器。

    执行器

    在执行器的阶段,此时会调用存储引擎的API,API会调用存储引擎,主要有一下存储的引擎,不过常用的还是myisam和innodb:

    666a8d90d83c30a58756046647a026ff.png

    引擎以前的名字叫做:表处理器(其实这个名字我觉得更能表达它存在的意义)负责对具体的数据文件进行操作,对SQL的语义比如select或者update进行分析,执行具体的操作。在执行完以后会将具体的操作记录到binlog中,需要注意的一点是:select不会记录到binlog中,只有update/delete/insert才会记录到binlog中。而update会采用两阶段提交的方式,记录都redolog中。

    执行的状态

    138dbdcd9a73b5a18b23d5e547068d1c.png

    可以通过命令:show full processlist,展示所有的处理进程,主要包含了以下的状态,表示服务器处理客户端的状态,状态包含了从客户端发起请求到后台服务器处理的过程,包括加锁的过程、统计存储引擎的信息,排序数据、搜索中间表、发送数据等。囊括了所有的MySQL的所有状态,其中具体的含义如下图:

    f09592e2ac4a8722ec6e666c31c39d00.png

    SQL的执行顺序

    5d9e110e9934fabe9d91d0fd2b4d48b4.png

    事实上,SQL并不是按照我们的书写顺序来从前往后、左往右依次执行的,它是按照固定的顺序解析的,主要的作用就是从上一个阶段的执行返回结果来提供给下一阶段使用,SQL在执行的过程中会有不同的临时中间表,一般是按照如下顺序:

    8cb37091ad21f73d899c2f10be5e1b8d.png

    例子: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;

    from

    第一步就是选择出from关键词后面跟的表,这也是SQL执行的第一步:表示要从数据库中执行哪张表。

    实例说明:在这个例子中就是首先从数据库中找到表T。

    join on

    join是表示要关联的表,on是连接的条件。通过from和join on选择出需要执行的数据库表T和S,产生笛卡尔积,生成T和S合并的临时中间表Temp1。on:确定表的绑定关系,通过on产生临时中间表Temp2。

    实例说明:找到表S,生成临时中间表Temp1,然后找到表T的id和S的id相同的部分组成成表Temp2,Temp2里面包含着T和Sid相等的所有数据。

    where

    where表示筛选,根据where后面的条件进行过滤,按照指定的字段的值(如果有and连接符会进行联合筛选)从临时中间表Temp2中筛选需要的数据,注意如果在此阶段找不到数据,会直接返回客户端,不会往下进行。这个过程会生成一个临时中间表Temp3。注意:在where中不可以使用聚合函数,聚合函数主要是(min\max\count\sum等函数)。

    实例说明:在temp2临时表集合中找到T表的name="Yrion"的数据,找到数据后会成临时中间表Temp3,T。emp3里包含name列为"Yrion"的所有表数据。

    group by

    group by是进行分组,对where条件过滤后的临时表Temp3按照固定的字段进行分组,产生临时中间表Temp4,这个过程只是数据的顺序发生改变,而数据总量不会变化,表中的数据以组的形式存在。

    实例说明:在Temp3表数据中对mobile进行分组,查找出mobile一样的数据,然后放到一起,产生Temp4临时表。

    Having

    对临时中间表Temp4进行聚合,这里可以为count等计数,然后产生中间表Temp5,在此阶段可以使用select中的别名。

    实例说明:在Temp4临时表中找出条数大于2的数据,如果小于2直接被舍弃掉,然后生成临时中间表Temp5。

    select

    对分组聚合完的表挑选出需要查询的数据,如果为*会解析为所有数据,此时会产生中间表Temp6。

    实例说明:在此阶段就是对Temp5临时聚合表中S表中的id进行筛选产生Temp6,此时Temp6就只包含有s表的id列数据,并且name="Yrion",通过mobile分组数量大于2的数据。

    Distinct

    Distinct对所有的数据进行去重,此时如果有min、max函数会执行字段函数计算,然后产生临时表Temp7。

    实例说明:此阶段对Temp5中的数据进行去重,引擎API会调用去重函数进行数据的过滤,最终只保留id第一次出现的那条数据,然后产生临时中间表Temp7。

    order by

    会根据Temp7进行顺序排列或者逆序排列,然后插入临时中间表Temp8,这个过程比较耗费资源。

    实例说明:这段会将所有Temp7临时表中的数据按照创建时间(create_time)进行排序,这个过程也不会有列或者行损失。

    limit

    limit对中间表Temp8进行分页,产生临时中间表Temp9,返回给客户端。

    实例说明:在Temp7中排好序的数据,然后取前五条插入到Temp9这个临时表中,最终返回给客户端。

    PS:实际上这个过程也并不是绝对这样的,中间MySQL会有部分的优化以达到最佳的优化效果,比如在select筛选出找到的数据集。

    总结

    d14ee75f406d241c072bd1ae1648cc63.png

    本篇博客总结了MySQL的执行过程,以及SQL的执行顺序,理解这些有助于我们对SQL语句进行优化,以及明白MySQL中的SQL语句从写出来到最终执行的轨迹,有助于我们对SQL有比较深入和细致的理解,提高我们的数据库理解能力。同时,对于复杂SQL的执行过程、编写都会有一定程度的意义。

    原文链接:https://www.cnblogs.com/wyq178/p/11576065.html

    Kubernetes线下实战与CKA培训

    ee671780d053ee8e67fc5bc54ef7d98d.png

    本次培训在北京开班,基于最新考纲,理论结合实战,通过线下授课、考题解读、模拟演练等方式,帮助学员快速掌握Kubernetes的理论知识和专业技能,并针对考试做特别强化训练,让学员能从容面对CKA认证考试,使学员既能掌握Kubernetes相关知识,又能通过CKA认证考试,理论、实践、考证一网打尽,学员可多次参加培训,直到通过认证。点击下方图片或者阅读原文链接查看详情。

    13568abedbee21c307dbc91eb373f0e7.png

    展开全文
  • MySQL执行过程及执行顺序

    千次阅读 2022-05-31 17:24:01
    一、MySQL执行过程 MySQL整体的执行过程如下图所示 1 1.1 连接器 1.1.1连接器的主要职责 1、负责与客户端的通信,是半双工模式,这就意味着某一固定时刻只能由客户端向服务器请求或者服务器向客户端发送...

    一、MySQL执行过程

    MySQL整体的执行过程如下图所示

    1

    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:

    2

    引擎以前的名字叫做:表处理器(其实这个名字我觉得更能表达它存在的意义)负责对具体的数据文件进行操作,对SQL的语义比如select或者update进行分析,执行具体的操作。在执行完以后会将具体的操作记录到binlog中,需要注意的一点是:select不会记录到binlog中,只有update/delete/insert才会记录到binlog中。而update会采用两阶段提交的方式,记录都redolog中。

    二、执行的状态

    可以通过命令:show full processlist,展示所有的处理进程,主要包含了以下的状态,表示服务器处理客户端的状态,状态包含了从客户端发起请求到后台服务器处理的过程,包括加锁的过程、统计存储引擎的信息,排序数据、搜索中间表、发送数据等。囊括了所有的MySQL的所有状态,其中具体的含义如下图:

    3

    三、SQL的执行顺序

    事实上,SQL并不是按照我们的书写顺序来从前往后、左往右依次执行的,它是按照固定的顺序解析的,主要的作用就是从上一个阶段的执行返回结果来提供给下一阶段使用,SQL在执行的过程中会有不同的临时中间表,一般是按照如下顺序:

    4

    5

    例子: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 MySQL

    MySQL 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语句做出最优的优化顺序,所以还是要我们自己预判断出哪种过滤是最优,毕竟自己才最懂自己的数据。



    作者:陈琰AC
    链接:https://www.jianshu.com/p/ff8bc0ec6365
     

    “做程序员,圈子和学习最重要”因为有有了圈子可以让你少走弯路,扩宽人脉,扩展思路,学习他人的一些经验及学习方法!同时在这分享一下是一直以来整理的Java后端进阶笔记文档和学习资料免费分享给大家!需要资料的朋友私信我扣【06】
     

    展开全文
  • sql和mysql执行顺序,发现内部机制是一样的。最大区别是在别名的引用上。 一、sql执行顺序 (1)from (2) on (3) join (4) where (5)group by(开始使用select中的别名,后面的语句中都可以使用) (6) avg,...
  • 大多时候MySQL会自动根据SQL语句做出优化,使用最优的SQL语句进行查询。有时候MySQL无法根据SQL语句做出最优的优化顺序,所以还是要我们自己预判断出哪种过滤是最优,毕竟自己才最懂自己的数据。...

    一、MySQL执行过程

    MySQL整体的执行过程如下图所示

    MySQL执行过程

    1.1 连接器

    1.1.1连接器的主要职责

    1、负责与客户端的通信,是半双工模式,这就意味着某一固定时刻只能由客户端向服务器请求或者服务器向客户端发送数据,而不能同时进行,其中MySQL在与客户端连接TCP/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会调用存储引擎,主要有以下存储的引擎,不过常用的还是myisaminnodb

    img

    引擎以前的名字叫做:表处理器(其实这个名字我觉得更能表达它存在的意义)负责对具体的数据文件进行操作,对SQL的语义比如select或者update进行分析,执行具体的操作。在执行完以后会将具体的操作记录到binlog中,需要注意的一点是:select不会记录到binlog中,只有update/delete/insert才会记录到binlog中。而update会采用两阶段提交的方式,记录都redolog中。

    二、执行的状态

    可以通过命令:show full processlist,展示所有的处理进程,主要包含了以下的状态,表示服务器处理客户端的状态,状态包含了从客户端发起请求到后台服务器处理的过程,包括加锁的过程、统计存储引擎的信息,排序数据、搜索中间表、发送数据等。囊括了所有的MySQL的所有状态,其中具体的含义如下图:

    img

    三、SQL的执行顺序

    事实上,SQL并不是按照我们的书写顺序来从前往后、左往右依次执行的,它是按照固定的顺序解析的,主要的作用就是从上一个阶段的执行返回结果来提供给下一阶段使用,SQL在执行的过程中会有不同的临时中间表,一般是按照如下顺序:

    img

    img

    例子: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 MySQL

    MySQL 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语句做出最优的优化顺序,所以还是要我们自己预判断出哪种过滤是最优,毕竟自己才最懂自己的数据。

    展开全文
  • MySQL执行顺序

    千次阅读 2022-02-26 22:52:43
    mysql执行顺序
  • MySQL执行过程

    2022-06-07 21:35:39
    深入理解MySQL执行过程及执行顺序MySQL整体的执行过程如下图所示:1、我们在客户端发起一个SQL的查询;2、连接器判断用户登录以及用户权限;3、缓存命中,走缓存,直接返回查询结果;3、缓存没命中,到达分析器,对...
  • MySQL执行过程以及顺序 前言:MySQL在我们的开发中基本每天都要面对的,作为开发中的数据的来源,MySQL承担者存储数据和读写数据的职责。因为学习和了解MySQL是至关重要的,那么当我们在客户端发起一个sql到出现详细的...
  • mysql执行顺序

    2018-03-28 18:55:15
    (1)from (2) on (3) ... (7)having (8) select (9) distinct (10) order by 从这个顺序中我们不难发现,所有的 查询语句都是从from开始执行的,在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这...
  • SELECT语句的完整语法为: (7) SELECT (8) DISTINCT <select_list> (1) FROM (3) <join> JOIN (2) ON (4) WHERE (5) GROUP BY (6) HAVING (9) ORDER BY ...说明:语法前面的序号为SELEC
  • select语句完整语法: SELECT DISTINCT <select_list> FROM <join> JOIN ON WHERE GROUP BY HAVING ORDER BY ...执行顺序: from →join →on →where →group by→having→select→order
  • 主要介绍了MySQL存储过程中实现执行动态SQL语句的方法,实例分析了MySQL中构造及执行动态SQL语句的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
  • Mysql 语句执行顺序

    千次阅读 2022-01-19 15:46:31
    一、Mysql 语法顺序 ...二、Mysql执行顺序 from on join where group by having select distinct union order by 注: 1)使用distinct要写在所有要查询字段的前面,后面有几个字段,就代表
  • Mysql执行顺序

    千次阅读 2019-06-10 23:20:56
    mysql执行sql的顺序从 From 开始,以下是执行的顺序流程 开始->FROM子句->WHERE子句->GROUP BY子句->HAVING子句->ORDER BY子句->SELECT子句->LIMIT子句->最终结果 1、FROM table1 left join...
  • drop PROCEDURE if exists my_procedure; create PROCEDURE my_procedure() BEGIN declare my_sqll varchar(500);... 您可能感兴趣的文章:mysql 存储过程中变量的定义与赋值操作mysql存储过程详解mysq
  • MySql执行顺序及执行计划

    万次阅读 多人点赞 2019-03-06 12:41:12
    mysql执行sql的顺序从 From 开始,以下是执行的顺序流程 1、FROM table1 left join table2 on 将table1和table2中的数据产生笛卡尔积,生成Temp1 2、JOINtable2 所以先是确定表,再确定关联条件 3、ONtable1....
  • MySql 语句执行顺序

    2021-01-19 19:51:37
    一、手写SQL顺序select from join on where group by having order by limit 二、MySql执行顺序from on join where group by having select distinctorder by limit 三、MySql执行顺序理解第一步:加载from子句的前...
  • Mysql存储过程执行顺序问题SQL code:CREATE TABLE `t_a` (`a_id` int(11) NOT NULL AUTO_INCREMENT,`a_name` varchar(30) NOT NULL DEFAULT 'N/A',PRIMARY KEY (`a_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;...
  • MySQL 各语句执行顺序

    千次阅读 2022-01-10 11:14:42
    目录 语句中各子句完整执行顺序概括(按照顺序执行): 每个子句执行顺序分析 语句中各子句完整执行顺序概括(按照顺序执行): ...所有的 查询语句都是从from开始执行的,在执行过程中,每个步骤都会为
  • MySQL 查询执行顺序

    2021-05-29 16:40:24
    目录前言一、SQL查询执行顺序二、具体步骤执行顺序简介1、执行FROM语句2、执行ON...MySQL 查询执行顺序?好吧,之前都没有看到过的一个知识点 一、SQL查询执行顺序 (7) SELECT (8) DISTINCT <select_list> (1) F
  • mysql的书写顺序执行顺序

    千次阅读 2021-11-14 17:30:28
    1.书写顺序 select * | 列名 -- 查询的列 from 表名 --查询哪些表 where 条件 --剔除不符合条件的 group by 分组的列 --指定根据哪些列分组 having 条件 --对分组之后的数据进行操作 order by --排序的列 limit a,b ...
  • MySQL语句执行顺序
  • mysql join的执行顺序??

    千次阅读 2021-01-30 02:16:17
    例1(left join && right join):select * from A ...// 最终返回的是 C 表中的数据,附带A、B两表中符合条件的数据// 这边的执行顺序是怎样的?// 我的理解:1. A left join B 返回 A 表数据,附带 B 表中...
  • mysql 存储过程 执行

    2021-01-21 08:46:19
    mysql存储过程mysql存储过程存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 732,230
精华内容 292,892
关键字:

mysql执行顺序

mysql 订阅
友情链接: 杂波模拟器.rar