SQL 查询的执行顺序是怎样呢?

好像这个问题应该很好回答,毕竟自己已经写了无数个 SQL 查询了,有一些还很复杂的。

但事实是,这个问题小编很难确切地说出它的顺序是怎样的。

言归正传,SELECT语句的完整语法如下:

SELECT
DISTINCT <select_list>
FROM <left_table>
<join_type> JOIN <right_table>
ON <join_condition>
WHERE <where_condition>
GROUP BY <group_by_list>
HAVING <having_condition>
ORDER BY <order_by_condition>
LIMIT <limit_number>

然而其执行顺序却是:

FROM
<表名> # 笛卡尔积
ON
<筛选条件> # 对笛卡尔积的虚表进行筛选
JOIN <join, left join, right join...>
<join表> # 指定join,用于添加数据到on之后的虚表中,例如left join会将左表的剩余数据添加到虚表中
WHERE
<where条件> # 对上述虚表进行筛选
GROUP BY
<分组条件> # 分组
<SUM()等聚合函数> # 用于having子句进行判断,在书写上这类聚合函数是写在having判断里面的
HAVING
<分组筛选> # 对分组后的结果进行聚合筛选
SELECT
<返回数据列表> # 返回的单列必须在group by子句中,聚合函数除外
DISTINCT
# 数据除重
ORDER BY
<排序条件> # 排序
LIMIT
<行数限制>

其实,引擎在执行上述每一步时,都会在内存中形成一张虚拟表,然后对虚拟表进行后续操作,并释放没用的虚拟表的内存,以此类推。

具体解释:(注:下面“VT”表示 → 虚拟表 virtual )

from:select * from table_1, table_2; 与 select * from table_1 join table_2; 的结果一致,都是表示求笛卡尔积;用于直接计算两个表笛卡尔积,得到虚拟表VT1,这是所有select语句最先执行的操作,其他操作时在这个表上进行的,也就是from操作所完成的内容

on: 从VT1表中筛选符合条件的数据,形成VT2表;

join: 将该 join 类型的数据补充到VT2表中,例如 left join 会将左表的剩余数据添加到虚表VT2中,形成VT3表;若表的数量大于2,则会重复1-3

where: 执行筛选,(不能使用聚合函数)得到VT4表;

group by: 对VT4表进行分组,得到VT5表;其后处理的语句,如select,having,所用到的列必须包含在group by条件中,没有出现的需要用聚合函数;

having: 筛选分组后的数据,得到VT6表;

select: 返回列得到VT7表;

distinct: 用于去重得到VT8表;

order by: 用于排序得到VT9表;

limit: 返回需要的行数,得到VT10;

需要注意的是:

  • group by条件中,每个列必须是有效列,不能是聚合函数;
  • null值也会作为一个分组返回;
  • 除了聚合函数,select子句中的列必须在group by条件中;

上述内容让我们知道一个查询会返回什么,同时,也回答了以下这些问题:

  • 可以在 GRROUP BY 之后使用 WHERE 吗?(不行,GROUP BY 是在 WHERE 之后!)
  • 可以对窗口函数返回的结果进行过滤吗?(不行,窗口函数是 SELECT 语句里,而 SELECT 是在 WHERE 和 GROUP BY 之后)
  • 可以基于 GROUP BY 里的东西进行 ORDER BY 吗?(可以,ORDER BY 基本上是在最后执行的,所以可以基于任何东西进行 ORDER BY)
  • LIMIT 是在什么时候执行?(在最后!)

但是,数据库引擎并不一定严格按照这个顺序执行 SQL 查询,因为为了更快地执行查询,它们会做出一些优化,这些问题会在下方进行解释↓↓↓。

SQL中的别名会影响SQL执行顺序么?

如下方SQL所示:

SELECT CONCAT(first_name, ' ', last_name) AS full_name, count(*)
FROM table
GROUP BY full_name

从这个语句来看,好像 GROUP BY 是在 SELECT 之后执行的,因为它引用了 SELECT 中的一个别名。但实际上不一定要这样,数据库引擎会把查询重写成这样↓↓↓:

SELECT CONCAT(first_name, ' ', last_name) AS full_name, count(*)
FROM table
GROUP BY CONCAT(first_name, ' ', last_name)

所以,这样 GROUP BY 仍然先执行。

另外,数据库引擎还会做一系列检查,确保 SELECT 和 GROUP BY 中的东西是有效的,所以会在生成执行计划之前对查询做一次整体检查。

数据库很可能不按正常顺序执行查询(优化)

在实际当中,数据库不一定会按照 JOIN、WHERE、GROUP BY 的顺序来执行查询,因为它们会进行一系列优化,把执行顺序打乱,从而让查询执行得更快,只要不改变查询结果。

这个查询说明了为什么需要以不同的顺序执行查询:

SELECT * FROM
dept d LEFT JOIN student s ON d.student_id = s.id
WHERE s.name = '陈哈哈'

如果只需要找出名字叫“陈哈哈”的学生信息,那就没必要对两张表的所有数据执行左连接,在连接之前先进行过滤,这样查询会快得多,而且对于这个查询来说,先执行过滤并不会改变查询结果。

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要

PHP进阶学习思维导图、面试;文档、视频资源免费获取​shimo.im

esp32查询剩余内存_SQL 查询语句先执行 SELECT?兄弟你认真的么?相关推荐

  1. 《DB 查询分析器》中断SQL语句的执行

    <DB 查询分析器>中断SQL语句的执行 马根峰 ( 广东联合电子收费股份有限公司, 广州 510300) 摘要     从事数据库查询.数据分析工作的人会经常遇到这样的情况,有些SQL语 ...

  2. 《软件》2011年第6期刊登出 《DB 查询分析器》中断SQL语句的执行

    <软件>编辑部寄来了2011年第6期样刊,在2011年第6期,刊登出了本人的论文------"<DB 查询分析器>中断SQL语句的执行". 论文刊登在第42 ...

  3. mysql语言中子查询是什么_SQL查询语句中,什么叫子查询?

    展开全部 嵌套SELECT语句也叫子查询,一个 SELECT 语句的查询结果能够作为另一个语句的输入值.子查询不但能够出现在Where子句3231313335323631343130323136353 ...

  4. 灵魂拷问,SQL 查询语句先执行 SELECT吗?

    大家平时和SQL语句打交道的时间肯定不少,有写过简单SQL的,也有为很复杂的业务逻辑的SQL绞尽脑汁的,那我在这里问下大家一个简单的问题:那你知道SQl语句的查询顺序是怎么样的吗? 当我刚看到这个问题 ...

  5. oracle查看执行最慢与查询次数最多的sql语句及其执行速度很慢的问题分析

    oracle查看执行最慢与查询次数最多的sql语句 注:本文来源 于<oracle查看执行最慢与查询次数最多的sql语句> 前言 在ORACLE数据库应用调优中,一个SQL的执行次数/频率 ...

  6. oracle一条sql运行时间很长,oracle查看执行最慢与查询次数最多的sql语句及其执行速度很慢的问题分析...

    oracle查看执行最慢与查询次数最多的sql语句 前言 在ORACLE数据库应用调优中,一个SQL的执行次数/频率也是常常需要关注的,因为某个SQL执行太频繁,要么是由于应用设计有缺陷,需要在业务逻 ...

  7. sql语句查询 日期比较_SQL查询比较日期

    sql语句查询 日期比较 For comparing dates in SQL, we use the DATE() function. The date should be in the DDMMY ...

  8. sql查询成绩最高分_sql查询各科成绩前三名----详述过程,思路清晰不烧脑!

    一.建表造数据 建表: create table scores( name varchar(100), subject varchar(100), score int ); 插入数据: insert ...

  9. 数据库查询求小于_SQL查询应用总结

    一. 模糊查询 知识点: like %表示任意字符串 1. 查询姓'猴'的学生名单 猴% 2.查询姓名中最后一个字是'猴'的学生名单 %猴 3. 查询姓名中带'猴'的学生名单 %猴% 4.查询姓&qu ...

最新文章

  1. openresty获取请求参数
  2. 运维-系统架构师经验总结:
  3. linux服务器centos系统apache路径不区分大小写的解决办法(适用WDCP面板)
  4. EJS 模板中,js 如何获取后端传来的数据
  5. WinCE内核裁减(中文字体)及字库和内核的分离(转)
  6. 探寻AI未来式,百度AI Studio两周年寻最强锦鲤送超大惊喜
  7. 变压器耦合和电容耦合_超越变压器和抱抱面的分类
  8. Exception in thread “main“ java.lang.IllegalStateException: Duplicate key xxx
  9. 设计模式之创建类模式PK
  10. mysql查看服务器CPU和内存_怎么查看服务器的cpu和内存的硬件信息
  11. 手把手教你crontab排障
  12. Matlab求矩阵均值
  13. 方立勋jdbc mysql视频_java视频教程 Java自学视频整理(持续更新中...)
  14. 2021年T电梯修理考试报名及T电梯修理试题及解析
  15. Pytorch-《Deep learning with pytorch》1.2.1训练imagenetmini
  16. 京东首页静态页面html+css
  17. mysql反三角函数,PostgreSQL中的函数之数学函数(正弦函数、反正弦函数、余弦函数、反余弦函数)...
  18. CUDA编程——GPU架构,由sp,sm,thread,block,grid,warp说起
  19. 怎么在mysql数据库中放图片_如何将图片储存在MySQL数据库中
  20. leetcode|剑指offter|面试题6:从尾到头打印链表

热门文章

  1. View Programming Guide for iOS官方文档翻译一
  2. 对thinkphp的命名空间的理解
  3. Swift -- 7.3 类和结构体
  4. windows 编程 —— 消息与参数(滚动条、键盘、鼠标)
  5. VS2013中修改.dll工程项目的.lib和.dll的输出路径
  6. BasKet Note Pads-利用软件作条记
  7. 一文了解 CVPR 2022 Workshop 都要做什么
  8. GAN也有脾气:「太难的部分我就不生成了,在下告退」
  9. 666! 玩王者,识英雄,这样也能上顶会!
  10. CVPR 2019 | 旷视提出新型目标检测损失函数:定位更精准