转载自:小强斋太-Study Notes,原文链接 从join on和where执行顺序认识T-SQL查询处理执行顺序

目录

一、样例

二、SELECT语句的处理过程

1. FROM阶段

2. WHERE阶段

3. GROUP BY阶段

4. HAVING阶段

5. SELECT阶段

6. ORDER BY阶段

三、样例解释

数据库SQL(Structure Query Language)包含3种类型的语言:DML(Data Manipulation Language)、DDL(Data Definition Language)和DCL(Data Control Language),其中使用最频繁的当属DML,DML包括4条具体的命令,它们是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言。这4条命令中,使用最频繁的是SELECT命令,所有查询的操作都是通过它来获取数据库中的数据。但你是否有思考过,数据库执行SELECT命令的顺序是否与我们写出的SELECT命令的顺序一致?接下来,我们就来分析一下Oracle数据库执行SELECT命令的顺序。

先通过一个例子来看JOIN ON和WHERE执行结果的不同。

一、样例

CREATE TABLE "SCOTT"."A" (

"PERSON_ID" NUMBER(5) NULL ,

"PERSON_NAME" VARCHAR2(255 BYTE) NULL 

)

;

-- ----------------------------

-- Records of A

-- ----------------------------

INSERT INTO "SCOTT"."A" VALUES ('', '张三');

INSERT INTO "SCOTT"."A" VALUES ('', '李四');

INSERT INTO "SCOTT"."A" VALUES ('', '王五');

INSERT INTO "SCOTT"."A" VALUES ('', '赵六');

INSERT INTO "SCOTT"."A" VALUES ('', '周七');

CREATE TABLE "SCOTT"."B" (

"PERSON_ID" NUMBER(5) NULL ,

"LOVE_FRUIT" VARCHAR2(255 BYTE) NULL 

);

-- ----------------------------

-- Records of B

-- ----------------------------

INSERT INTO "SCOTT"."B" VALUES ('', '香蕉');

INSERT INTO "SCOTT"."B" VALUES ('', '苹果');

INSERT INTO "SCOTT"."B" VALUES ('', '橘子');

INSERT INTO "SCOTT"."B" VALUES ('', '梨');

INSERT INTO "SCOTT"."B" VALUES ('', '桃');

查询语句1

SELECT * FROM A LEFT JOIN ORACLE.B ON A.PERSON_ID = B.PERSON_ID AND A.PERSON_ID = 1;

查询语句2

SELECT * FROM A LEFT JOIN ORACLE.B ON A.PERSON_ID = B.PERSON_ID WHERE A.PERSON_ID = 1;

为什么结果不同呢?可以从查询逻辑处理的过程解释。

二、SELECT语句的处理过程

我们知道,SQL 查询的大致语法结构如下:

(5)SELECT DISTINCT TOP(<top_specification>) <select_list>                     

(1)FROM <left_table> <join_type> JOIN <right_table> ON <on_predicate>

(2)WHERE <where_predicate>

(3)GROUP BY <group_by_specification>

(4)HAVING <having_predicate>

(6)ORDER BY <order_by_list>

SELECT语法的处理顺序:

The following steps show the processing order for a SELECT statement.

  1. FROM
  2. ON
  3. JOIN
  4. WHERE
  5. GROUP BY
  6. WITH CUBE or WITH ROLLUP
  7. HAVING
  8. SELECT
  9. DISTINCT
  10. ORDER BY
  11. TOP

这些步骤执行时,每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。这些虚拟表对调用者(客户端应用程序或者外部查询)不可用。只是最后一步生成的表才会返回给调用者。如果没有在查询中指定某一子句,将跳过相应的步骤。

SELECT各个阶段分别干了什么:

1. FROM阶段

FROM阶段标识出查询的来源表,并处理表运算符。在涉及到联接运算的查询中(各种JOIN),主要有以下几个步骤:

  • 求笛卡尔积。不论是什么类型的联接运算,首先都是执行交叉连接(CROSS JOIN),求笛卡儿积,生成虚拟表VT1-J1。
  • ON筛选器。  这个阶段对上个步骤生成的VT1-J1进行筛选,根据ON子句中出现的谓词进行筛选,让谓词取值为true的行通过了考验,插入到VT1-J2。
  • 添加外部行。如果指定了OUTER JOIN,还需要将VT1-J2中没有找到匹配的行,作为外部行添加到VT1-J2中,生成VT1-J3。

经过以上步骤,FROM阶段就完成了。概括地讲,FROM阶段就是进行预处理的,根据提供的运算符对语句中提到的各个表进行处理(除了JOIN,还有APPLY,PIVOT,UNPIVOT)。

2. WHERE阶段

WHERE阶段是根据<where_predicate>中条件对VT1中的行进行筛选,让条件成立的行才会插入到VT2中。

3. GROUP BY阶段

GROUP阶段按照指定的列名列表,将VT2中的行进行分组,生成VT3。最后每个分组只有一行。

4. HAVING阶段

该阶段根据HAVING子句中出现的谓词对VT3的分组进行筛选,并将符合条件的组插入到VT4中。

5. SELECT阶段

这个阶段是投影的过程,处理SELECT子句提到的元素,产生VT5。这个步骤一般按下列顺序进行:

  • 计算SELECT列表中的表达式,生成VT5-1。
  • 若有DISTINCT,则删除VT5-1中的重复行,生成VT5-2。
  • 若有TOP,则根据ORDER BY子句定义的逻辑顺序,从VT5-2中选择签名指定数量或者百分比的行,生成VT5-3。

6. ORDER BY阶段

根据ORDER BY子句中指定的列明列表,对VT5-3中的行,进行排序,生成游标VC6。

三、样例解释

查询语句1的执行过程

SELECT * FROM A LEFT JOIN ORACLE.B ON A.PERSON_ID = B.PERSON_ID AND A.PERSON_ID = 1;

求笛卡尔积,产生5*5=25条记录

A.PERSON_ID

PERSON_NAME

B.PERSON_ID

LOVE_FRUIT

1

张三

1

香蕉

1

张三

2

苹果

1

张三

3

橘子

1

张三

4

1

张三

8

2

李四

1

香蕉

2

李四

2

苹果

2

李四

3

橘子

2

李四

4

2

李四

8

3

王五

1

香蕉

3

王五

2

苹果

3

王五

3

橘子

3

王五

4

3

王五

8

4

赵六

1

香蕉

4

赵六

2

苹果

4

赵六

3

橘子

4

赵六

4

4

赵六

8

5

周七

1

香蕉

5

周七

2

苹果

5

周七

3

橘子

5

周七

4

5

周七

8

ON筛选器(A.PERSON_ID=B.PERSON_ID AND A.PERSON_ID=1)

A.PERSON_ID

PERSON_NAME

B.PERSON_ID

LOVE_FRUIT

1

张三

1

香蕉

添加外部行

A.PERSON_ID

PERSON_NAME

B.PERSON_ID

LOVE_FRUIT

1

张三

1

香蕉

1

张三

1

张三

1

张三

1

张三

查询语句2的执行过程

SELECT * FROM A LEFT JOIN ORACLE.B ON A.PERSON_ID = B.PERSON_ID WHERE A.PERSON_ID = 1;

求笛卡尔积,产生5*5=25条记录

A.PERSON_ID

PERSON_NAME

B.PERSON_ID

LOVE_FRUIT

1

张三

1

香蕉

1

张三

2

苹果

1

张三

3

橘子

1

张三

4

1

张三

8

2

李四

1

香蕉

2

李四

2

苹果

2

李四

3

橘子

2

李四

4

2

李四

8

3

王五

1

香蕉

3

王五

2

苹果

3

王五

3

橘子

3

王五

4

3

王五

8

4

赵六

1

香蕉

4

赵六

2

苹果

4

赵六

3

橘子

4

赵六

4

4

赵六

8

5

周七

1

香蕉

5

周七

2

苹果

5

周七

3

橘子

5

周七

4

5

周七

8

ON筛选器 (A.PERSON_ID=B.PERSON_ID)

A.PERSON_ID

PERSON_NAME

B.PERSON_ID

LOVE_FRUIT

1

张三

1

香蕉

2

李四

2

苹果

3

王五

3

橘子

4

赵六

4

添加外部行

A.PERSON_ID

PERSON_NAME

B.PERSON_ID

LOVE_FRUIT

1

张三

1

香蕉

2

李四

2

苹果

3

王五

3

橘子

4

赵六

4

5

周七

WHERE阶段 (A.PERSON_ID=1)

A.PERSON_ID

PERSON_NAME

B.PERSON_ID

LOVE_FRUIT

1

张三

1

香蕉

有了上面的验证,我们可以猜测下面语句的执行结果

SELECT * FROM  A LEFT JOIN ORACLE.B ON A.PERSON_ID = B.PERSON_ID;

Oracle(二)SELECT语句执行顺序的更多相关文章

  1. Select 语句执行顺序以及如何提高Oracle 基本查询效率

    今天把这几天做的练习复习了一下,不知道自己写得代码执行的效率如何以及要如何提高,于是乎上网开始研究一些材料,现整理如下: 首先,要了解在Oracle中Sql语句运行的机制.以下是sql语句的执行步骤: ...

  2. SQL select语句执行顺序

    sql查询原理和Select执行顺序 关键字: 数据库 一 sql语句的执行步骤 1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义. 2) 语义分析,检查语句中涉及的所有数据库对象是 ...

  3. MySQL(五)SELECT语句执行顺序

    上一篇讲述了Oracle的SELECT语法的执行顺序,这篇讲述MySQL的SELECT语法的执行顺序.MySQL的SELECT语法的执行顺序和Oracle的基本相同,只是增加了MySQL独有的LIMI ...

  4. SQL之SELECT语句执行顺序及子句功能

    1.select 语句的执行顺序 SELECT a.id,a.`product_name`,a.`agreement_copies` i,b.id as statusId from `opmp_pro ...

  5. mysql select语句执行顺序

        SELECT语句定义       一个完成的SELECT语句包含可选的几个子句. SELECT语句的定义如下: <SELECT clause> [<FROM clause&g ...

  6. Select语句执行顺序《转》

    原文发布时间为:2010-10-12 -- 来源于本人的百度文章 [由搬家工具导入] 目的在于理解如何Select 【搜索所得】: 标准的 SQL 的解析顺序为:(1).FROM 子句, 组装来自不同 ...

  7. 关于sql和MySQL的语句执行顺序(必看!!!)

    今天遇到一个问题就是mysql中insert into 和update以及delete语句中能使用as别名吗?目前还在查看,但是在查阅资料时发现了一些有益的知识,给大家分享一下,就是关于sql以及My ...

  8. 关于sql和MySQL的语句执行顺序

    sql和mysql执行顺序,发现内部机制是一样的.最大区别是在别名的引用上. 一.sql执行顺序 (1) from (3) join (2) on (4) where (5) group by(开始使 ...

  9. (转)关于sql和MySQL的语句执行顺序(必看!!!)

    原文:https://blog.csdn.net/u014044812/article/details/51004754 https://blog.csdn.net/j080624/article/d ...

随机推荐

  1. linux命令更改服务器时间

    1. linux更改服务器时间: 权限:root用户才有权限更改服务器时间 使用date命令即可设置系统时间. 2. 查看系统时间 date 3. 设置当前系统时间为2015年5月8日19点48分0秒 ...

  2. c#+arcAE对图层进行各种渲染操作

    转载:http://blog.sina.com.cn/s/blog_6023833e0100t5t0.html using System;using System.Collections.Generi ...

  3. jQuery 四舍五入

    var a="15.23456789"; var b=a.toFixed(2);/*保留两位小数*/ alert(b); /*返回结果:15.23*/

  4. 无法在类...中找到资源".bmp"

    在WinForm中写的一个程序,在项目中添加了一个bmp图片,然后 public void SetSubType(int SubType) { m_subType = SubType; switch ...

  5. Global Average Pooling Layers for Object Localization

    For image classification tasks, a common choice for convolutional neural network (CNN) architecture ...

  6. iphone使用linux命令apt-get也没有问题

    那么教程开始: 首先安装cydia这个越了yu就有自带的哦 然后添加源,比如apt.91.我忘了,大家可以在http://frank-dev-blog.club/?post=45找一个 查找termi ...

  7. ORACLE学习文档

    转自 http://sparklet.blog.sohu.com/523655.html 数据库被分成一个或多个逻辑部件称作表空间.而表空间又被分成称作段(segment)的逻辑部件.这些段再细分就叫 ...

  8. HDFS pipeline写 -- 客户端

    上一篇说了datanode端如何处理pipeline写请求的,这里主要看DFSClient. 这里以append为例, write差不多. 创建一个pipeline用于append操作的流程: Fil ...

  9. 制作 OS X El Capitan 启动盘

    制作 OS X El Capitan 启动盘 1. 下载系统盘的dmg格式 2. 直到出现了 3. 在命令行中找到 Install OS X El Capitan.app 4. 格式化你的U盘(U盘名 ...

  10. WDS使用捕获映像制作企业自定义映像

    来源:http://www.07net01.com/linux/WDSshiyongbuhuoyingxiangzhizuoqiyezidingyiyingxiang_545749_137448761 ...