Mysql中Select语句的执行顺序

目录

前言

试验环境

一、语句结构

二、执行步骤

三、查询过程

四、疑问

总结

前言

今天同事问了我个问题,select语句中的别名可以在哪些地方使用,一听这个我就想到了聚合函数、group by、having、order by 。然后它又问我可以在 join on中使用嘛?,我陷入了思考,想了下这其实跟select语句的执行顺序有关,因为记不太清了,所以再次学习了下,并记录一下。

试验环境

Mysql 5.7

一、语句结构

SELECT DISTINCT ...,...,...
FROM ...
JOIN ... ON ... 多表的连接条件
JOIN ... ON ...
WHERE ... AND/OR... 不包含组函数的过滤条件
GROUP BY ...,...
HAVING ... 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...

二、执行步骤

在MySQL中,SELECT语句的执行顺序可以分为以下几个步骤:

  1. FROM子句:首先,MySQL会从FROM子句中指定的表中检索数据。如果FROM子句中包含多个表,MySQL会根据连接条件将它们连接起来。

  2. ON子句:接下来,MySQL会根据ON子句中的条件过滤出符合条件的数据。

  3. WHERE子句:然后,MySQL会根据WHERE子句中的条件过滤出符合条件的数据。只有符合WHERE条件的数据才会被查询出来。

  4. GROUP BY子句:如果查询语句中有GROUP BY子句,MySQL会根据GROUP BY子句中指定的列对查询结果进行分组。每个分组都会有一个唯一的组标识。

  5. 聚合函数

  6. HAVING子句:如果查询语句中有HAVING子句,MySQL会根据HAVING子句中的条件过滤出符合条件的分组。只有符合HAVING条件的分组才会被查询出来。

  7. SELECT子句:接下来,MySQL会根据SELECT子句中指定的列从查询结果中提取出需要的数据。

  8. DISTINCT关键字:如果查询语句中包含DISTINCT关键字,MySQL会去除查询结果中的重复行。

  9. ORDER BY子句:如果查询语句中有ORDER BY子句,MySQL会根据ORDER BY子句中指定的列对查询结果进行排序。

  10. LIMIT子句:最后,如果查询语句中有LIMIT子句,MySQL会根据LIMIT子句指定的数量限制查询结果的行数。

总体来说,SELECT语句的执行顺序是按照以上步骤逐步执行的。根据查询语句中的不同子句,MySQL会在执行过程中进行不同的操作,最终返回符合条件的查询结果。

三、查询过程

  1. 首先根据FROM后边的前两个表做一个笛卡尔积生成虚拟表table1,对应步骤1
    笛卡尔积
    
    笛卡尔积是集合论中的一个概念,表示两个集合的所有可能的有序对组成的集合。
    
    假设A和B是两个集合,A={a, b},B={1, 2}。那么A和B的笛卡尔积可以表示为A×B
    ={(a, 1), (a, 2), (b, 1), (b, 2)}。
    
    简单来说,笛卡尔积就是将两个集合的每个元素进行组合,得到所有可能的有序对。
    结果集合中的每个元素都由一个A中的元素和一个B中的元素组成,且顺序不同则为
    不同的元素。
  2. 然后根据ON语句的条件对table1进行筛选生成table2,对应步骤2
  3. 然后根据连接关键字Left、Right、Outer等,对table2进行补充形成table3
    具体过程
    Left 左表为基础表,右表对应数据不存在则为Null,形成新的虚拟表
    RIGHT 右表为基础表,左表对应数据不存在则为Null,形成新的虚拟表
  4. 如果超过两张表就重复1-3最终形成虚拟表table4
  5. 通过where语句进行筛选,形成虚拟表table5,对应步骤3
  6. 有group by 语句,就对table5分组形成 虚拟表table6,对应步骤4
  7. 应用cube或者rollup选项,生成超组,对分组后结果执行聚合函数形成虚拟表table7,对应步骤5
    cube、rollup选项是什么?
    
    CUBE和ROLLUP都是用于生成多维聚合报表的选项。
    
    CUBE选项允许在GROUP BY子句中同时生成多个聚合级别的汇总数据。它会生成所有可能的组合,
    包括空值。例如,如果有两个维度A和B,那么CUBE(A, B)将生成包括(A,B),(A,NULL),
    (NULL,B)和(NULL,NULL)的所有组合。
    
    ROLLUP选项类似于CUBE,但是它只生成按照指定顺序的聚合级别。ROLLUP(A, B)将生成(A,B)
    ,(A,NULL)和(NULL,NULL)这三个级别的组合。
    
  8. 执行having 语句,对分组进行筛选形成虚拟表table8,对应步骤6
  9. 应用select语句,保留相应的列,生成虚拟表table9,对应步骤7
  10. 有DISTINCT语句,移除重复行,生成虚拟表table10,对应步骤8
  11. 执行order by子句,此时返回的一个游标,对应步骤9
    什么是游标?
    MySQL游标是一个用于在数据集上进行迭代的数据库对象。它类似于在编程中使用的游标概念,
    可以将游标看作是一个指针,可以依次访问数据集中的每一行。
  12. Limit筛选返回的数据条数,对应步骤10

四、疑问

分析完mysql的执行顺序,很明显别名不可以在join on中使用,因为join on在select之前就执行了,但是我又产生了新的疑问:

  1. select在group by之后执行,为什么group by中可以使用别名?
  2. 用on筛选和用where筛选有什么区别?
  3. order by在select之后,为什么order by可以用select中未选择的列呢?

问题1:select在group by之后执行,为什么group by中可以使用别名?

mysql官网也没有给出具体原因
mysql官网解释

但目前可以确定的是:select肯定在group by之前执行了一次,可以理解成在原有顺序的基础上的预加载,也就是说对于mysql,每一次运行代码,实际上执行了至少两次select。

问题2:用on筛选和用where筛选有什么区别?

on和where的最大区别在于,如果在on应用逻辑表达式那么在第三步join中还可以把移除的行再次添加回来,而where的移除的最终的;

问题3:order by在select之后,为什么order by可以用select中未选择的列呢?

没找到答案,希望大佬可以解惑。

总结

本文总结了mysql中select的执行顺序,并对几个常见的疑问进行了解答,希望能对你有所帮助。

  • 35
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: MySQLSELECT语句执行顺序如下: 1. FROM:指定要查询的表或视图。 2. JOIN:如果查询涉及到多个表,需要使用JOIN关键字将它们连接起来。 3. WHERE:指定查询条件,只有符合条件的记录才会被返回。 4. GROUP BY:按照指定的列对结果进行分组。 5. HAVING:指定分组后的条件,只有符合条件的分组才会被返回。 6. SELECT:指定要查询的列。 7. DISTINCT:去除重复的记录。 8. ORDER BY:指定结果的排序方式。 9. LIMIT:指定返回结果的数量。 以上是MySQL SELECT语句执行顺序,需要注意的是,不是所有的SELECT语句都需要按照这个顺序执行,有些语句可能会省略其的一些步骤。 ### 回答2: MySQLSELECT语句执行顺序可以分为以下9个步骤: 1. 执行FROM子句,获取表的数据。 2. 执行WHERE子句,筛选出符合条件的数据。 3. 执行GROUP BY子句,将数据按照指定的列进行分组。 4. 执行HAVING子句,筛选出符合条件的分组。 5. 执行SELECT子句,选择需要查询的列。 6. 执行DISTINCT关键字,去除重复的行。 7. 执行ORDER BY子句,按照指定的列对结果集进行排序。 8. 执行LIMIT子句,指定返回的结果数量。 9. 最后输出查询结果。 需要注意的是,执行顺序并不一定按照上述顺序执行,某些步骤可能被优化或者省略,例如如果查询没有WHERE子句,则不需要执行WHERE子句。此外,MySQL还支持查询缓存,如果查询缓存已经存在相同的查询结果,则直接返回缓存结果,不需要执行上述步骤。 在优化查询性能时,可以使用多种技巧来优化各个步骤。例如,可以使用索引来加速查询的WHERE条件,使用分区表来加速GROUP BY操作,使用EXPLAIN关键字来分析查询性能等。 ### 回答3: MySQLSELECT语句是关系型数据库最常用的查询语句,在操作数据时必须掌握其执行顺序SELECT语句执行顺序分为以下六个步骤: 1. FROM子句:指定要查询的表及其所在的数据库。如果在查询时使用了多个表,那么就需要使用JOIN等操作将这些表联接起来。 2. JOIN子句:根据指定的连接条件将要查询的表连接起来。JOIN子句在FROM子句之后执行,但是在WHERE子句之前执行。 3. WHERE子句:指定查询的条件。WHERE子句在JOIN子句之后执行,但是在GROUP BY子句之前执行。 4. GROUP BY子句:将查询的结果分组。GROUP BY子句在WHERE子句之后执行,但是在HAVING子句之前执行。 5. HAVING子句:指定按组过滤后的查询结果。HAVING子句在GROUP BY子句之后执行,但是在SELECT子句之前执行。 6. SELECT子句:指定要查询的列及其计算方式。SELECT子句在所有子句最后执行。 需要注意的是,SELECT语句的ORDER BY子句并不是查询执行顺序的一部分,而是在查询结束后对查询结果进行排序的语句。因此,ORDER BY子句总是在SELECT语句执行完毕之后执行。 总之,了解SELECT语句执行顺序是操作关系型数据库的基本要求,只有深入理解每个步骤的顺序,才能更好地优化数据库查询的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alpaca Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值