您当前的位置: 首页 >  sql

liaowenxiong

暂无认证

  • 0浏览

    0关注

    1171博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

SQL语句执行顺序

liaowenxiong 发布时间:2020-07-24 07:06:24 ,浏览量:0

文章目录
  • SQL 简介
  • SQL 语句的执行顺序
  • 重点

SQL 简介

SQL 是 Structured Query Language 的缩写,称为结构化查询语言,SQL 是一种操作关系型数据库的规则,SQL 语句以分号结尾,不区分大小写,建议关键词使用大写。

SQL 语句的执行顺序

(7) SELECT (8) DISTINCT (1) FROM (3) JOIN (2) ON (4) WHERE (5) GROUP BY (6) HAVING (9) ORDER BY (10) LIMIT 在这里插入图片描述

下面我们来具体分析一下查询处理的每一个阶段:

FORM:FROM 的左边的表和右边的表计算笛卡尔积。产生虚拟表 VT1

ON: 对虚拟表 VT1 进行 ON 筛选,只有那些符合 的行才会被记录在虚拟表 VT2 中。

JOIN: 如果指定了 OUTER JOIN(比如 left joinright join),那么保留表中未匹配的行就会作为外部行添加到虚拟表 VT2 中,产生虚拟表 VT3, 如果 from 子句中包含两个以上的表的话,那么就会对上一个 join 连接产生的结果 VT3 和下一个表重复执行步骤1~3这三个步骤,一直到处理完所有的表为止。

WHERE: 对虚拟表 VT3 进行 WHERE 条件过滤。只有符合 的记录才会被插入到虚拟表 VT4 中。

GROUP BY: 根据 group by 子句中的列,对 VT4 中的记录进行分组操作,产生虚拟表 VT5

CUBE | ROLLUP: 对表 VT5 进行 cube 或者 rollup 操作,产生虚拟表 VT6

HAVING: 对虚拟表 VT6 应用 having 过滤,只有符合 的记录才会被 插入到虚拟表 VT7 中。

SELECT: 执行 select 操作,选择指定的列,并对字段进行处理,计算 select 子句中的表达式,产生虚拟表 VT8

DISTINCT:VT8 中的记录进行去重。产生虚拟表 VT9

ORDER BY: 将虚拟表 VT9 中的记录按照 进行排序操作,返回游标 VC10,而不是虚拟表。SQL 是基于集合理论的,集合不会预先对它的行排序,它只是成员的逻辑集合,成员的顺序是无关紧要的。对表进行排序的查询可以返回一个对象,这个对象包含特定的物理顺序的逻辑组织。这个对象就叫游标。正因为返回值是游标,那么使用 ORDER BY 子句查询不能应用于表表达式。排序是很需要成本的,除非你必须要排序,否则最好不要指定 ORDER BY。这一步是第一步也是唯一一步可以使用 SELECT 列表中的列别名的步骤。

LIMIT:VC10 的开始处选择指定数量行,生成虚拟表 VT11,并将结果返回。

写的顺序:

select ... from... where.... group by... having... order by.. limit...

执行顺序:

from... where...group by... having.... select ... order by... limit... 
重点

错误的理解:

select … where,where 子句比 selec 子句先执行,但是数据库是逐行判断的,也就是说数据库在执行 SQL 语句时,指针会移动到表中的第一行,先判断第一行记录是否满足 where 子句的条件,满足则执行 select 子句,将整行记录的所有字段值存储到虚拟表中(注意:如果 select 子句中自定义了其它字段,那么这个步骤会将自定义的字段及相关的字段值存储到虚拟表中)。接着移动指针到下一行,再判断是否满足 where 子句的条件;如果不满足则放弃该条记录,接着指针移到下一行,再判断是否满足 where 子句的条件。重复上述的流程直到无记录可读取为止。

但是最终在返回查询结果时,selec 子句指定了什么字段,返回的结果集中则包含哪些字段。

正确的理解:

先逐行判断记录是否满足 where 子句的条件,不满足则放弃,满足则将整行记录的字段值存储到虚拟表 VT0 中,直到整张表的数据筛选完成后,再执行 select 子句从虚拟表 VT0 中获取指定的列和值到虚拟表 VT1 中,最后将结果返回。

如果 select 子句中含有变量表达式,在执行 where 子句时,有时候这些表达式会同步进行计算,而有的时候不会计算,具体什么情况下会计算,什么情况下不会计算,我也不清楚。但是这里要提醒的是,即便表达式同步计算了,并不表示 select 子句在执行,所以不要以为变量的值发生变化了就认为 where 子句执行完后紧跟着就执行了 select 子句,其实并不是这样的。

关注
打赏
1661566967
查看更多评论
立即登录/注册

微信扫码登录

0.7438s