Oracle(二)SELECT语句执行顺序
目录
一、样例
二、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.
- FROM
- ON
- JOIN
- WHERE
- GROUP BY
- WITH CUBE or WITH ROLLUP
- HAVING
- SELECT
- DISTINCT
- ORDER BY
- 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语句执行顺序的更多相关文章
- Select 语句执行顺序以及如何提高Oracle 基本查询效率
今天把这几天做的练习复习了一下,不知道自己写得代码执行的效率如何以及要如何提高,于是乎上网开始研究一些材料,现整理如下: 首先,要了解在Oracle中Sql语句运行的机制.以下是sql语句的执行步骤: ...
- SQL select语句执行顺序
sql查询原理和Select执行顺序 关键字: 数据库 一 sql语句的执行步骤 1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义. 2) 语义分析,检查语句中涉及的所有数据库对象是 ...
- MySQL(五)SELECT语句执行顺序
上一篇讲述了Oracle的SELECT语法的执行顺序,这篇讲述MySQL的SELECT语法的执行顺序.MySQL的SELECT语法的执行顺序和Oracle的基本相同,只是增加了MySQL独有的LIMI ...
- SQL之SELECT语句执行顺序及子句功能
1.select 语句的执行顺序 SELECT a.id,a.`product_name`,a.`agreement_copies` i,b.id as statusId from `opmp_pro ...
- mysql select语句执行顺序
SELECT语句定义 一个完成的SELECT语句包含可选的几个子句. SELECT语句的定义如下: <SELECT clause> [<FROM clause&g ...
- Select语句执行顺序《转》
原文发布时间为:2010-10-12 -- 来源于本人的百度文章 [由搬家工具导入] 目的在于理解如何Select 【搜索所得】: 标准的 SQL 的解析顺序为:(1).FROM 子句, 组装来自不同 ...
- 关于sql和MySQL的语句执行顺序(必看!!!)
今天遇到一个问题就是mysql中insert into 和update以及delete语句中能使用as别名吗?目前还在查看,但是在查阅资料时发现了一些有益的知识,给大家分享一下,就是关于sql以及My ...
- 关于sql和MySQL的语句执行顺序
sql和mysql执行顺序,发现内部机制是一样的.最大区别是在别名的引用上. 一.sql执行顺序 (1) from (3) join (2) on (4) where (5) group by(开始使 ...
- (转)关于sql和MySQL的语句执行顺序(必看!!!)
原文:https://blog.csdn.net/u014044812/article/details/51004754 https://blog.csdn.net/j080624/article/d ...
随机推荐
- bzoj P1058 [ZJOI2007]报表统计——solution
1058: [ZJOI2007]报表统计 Time Limit: 15 Sec Memory Limit: 162 MB Submit: 4099 Solved: 1390 [Submit][St ...
- 前端日报-20160527 underscore 源码解读
underscore 源码解读 API文档浏览器 JavaScript 中加号操作符细节 抛弃 jQuery,拥抱原生 JS 从 0 开始学习 GitHub 系列之「加入 GitHub」 js实现克隆 ...
- 阿里云短信服务Java版
短信服务管理平台 https://dysms.console.aliyun.com/dysms.htm java短信发送API https://help.aliyun.com/document_ ...
- JSON学习笔记-1
1.什么是JSON? JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式.它基于 ECMAScript (欧洲计算机协会制定的js规范)的一 ...
- Android使用xml文件中的array资源
Android中有种使用数组的非常简单的用法,在xml文件中获取. 创建数组资源 在value目录下创建arrays.xml文件 然后在arrays.xml文件中使用<string-array& ...
- react-ssr
为什么使用SSR 与传统 SPA(Single-Page Application - 单页应用程序)相比 服务器端渲染(SSR)的优势主要在于: 更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完 ...
- ActiveMq--消息队列
ActiveMQ官网下载地址:http://activemq.apache.org/download.html ActiveMQ的目录: bin存放的是脚本文件 conf存放的是基本配置文件 data ...
- 0. 跟踪标记 (Trace Flag) 简介
一. 什么是跟踪标记 SQL Server 跟踪标记(Trace Flag),像是一个开关,可用来自定义SQL Server的某种行为或特性,在性能诊断,系统调试等方面较为常用.比如:开启1204或1 ...
- UIButton的两种block传值方式
UIButton的两种block传值方式 方式1 - 作为属性来传值 BlockView.h 与 BlockView.m // // BlockView.h // Block // // Create ...
- [翻译] DCPathButton
DCPathButton https://github.com/Tangdixi/DCPathButton DCPathButton 2.0 is a menu button for iOS. Des ...