Mysql-SQL执行顺序

2024-03-10 21:19:04 浏览数 (1)

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

clipboard.pngclipboard.png
代码语言:java复制
例子: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、from
        第一步就是选择出from关键词后面跟的表,这也是sql执行的第一步:表示要从数据库中执行哪张表。
        实例说明:在这个例子中就是首先从数据库中找到表T
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和s.id相等的所有数据
3、where
        where表示筛选,根据where后面的条件进行过滤,按照指定的字段的值(如果有and连接符会进行联合筛选)从临时中间表Temp2中筛选需要的数据,
        注意如果在此阶段找不到数据,会直接返回客户端,不会往下进行,这个过程会生成一个临时中间表Temp3。
        注意在where中不可以使用聚合函数,聚合函数主要是(minmaxcountsum等函数)
        实例说明:在temp2临时表集合中找到T表的name="Yrion"的数据,找到数据后会成临时中间表Temp3,temp3里包含name列为"Yrion"的所有表数据
4、group by (按条件关键字分组,剔除重复的)
        group by是进行分组,对where条件过滤后的临时表Temp3按照固定的字段进行分组,产生临时中间表Temp4,
        "这个过程只是数据的顺序发生改变,而数据总量不会变化,表中的数据以组的形式存在"
        实例说明:在temp3表数据中对mobile进行分组,查找出mobile一样的数据,然后放到一起,产生temp4临时表。
        https://mp.weixin.qq.com/s?__biz=MzU2MTY3NTA0Ng==&mid=2247483822&idx=1&sn=b39c341718cf76021e1b6a06fbf0b666&chksm=fc746fe7cb03e6f1d7d490a5a3390dc1f9d4f52e08fe2494d3f3b2717e5a588b43d3c1fbfb8b&scene=27
5、Having (聚合函数)
        对临时中间表Temp4进行聚合,这里可以为count等计数,然后产生中间表Temp5,在此阶段可以使用select中的别名
        实例说明:在temp4临时表中找出条数大于2的数据,如果小于2直接被舍弃掉,然后生成临时中间表temp5
6、select  (select子句后的任一非聚合函数字段都应来源于group by 分组语句后,否则语法会编译不通过)
        对分组聚合完的表挑选出需要查询的数据,如果为*会解析为所有数据,此时会产生中间表Temp6
        实例说明:在此阶段就是对temp5临时聚合表中含有S表中的id进行筛选产生Temp6,
                 此时temp6就只包含有s表的id列数据,并且name="Yrion",通过mobile分组数量大于2的数据
7、Distinct
        distinct对所有的数据进行去重,此时如果有min、max函数会执行字段函数计算,然后产生临时表Temp7
        实例说明:此阶段对temp5中的数据进行去重,引擎API会调用去重函数进行数据的过滤,最终只保留id第一次出现的那条数据,然后产生临时中间表temp7
8、order by (order by后的字段必须来源于group by分组字段)
        会根据Temp7进行顺序排列或者逆序排列,然后插入临时中间表Temp8,这个过程比较耗费资源
        实例说明:这段会将所有temp7临时表中的数据按照创建时间(create_time)进行排序,这个过程也不会有列或者行损失
9、limit
        limit对中间表Temp8进行分页,产生临时中间表Temp9,返回给客户端。
        实例说明:在temp7中排好序的数据,然后取前五条插入到Temp9这个临时表中,最终返回给客户端
ps:实际上这个过程也并不是绝对这样的,中间mysql会有部分的优化以达到最佳的优化效果,比如在select筛选出找到的数据集

0 人点赞