SQL语句执行顺序详解

我们做软件开发的,大部分人都离不开跟数据库打交道,特别是erp开发的,跟数据库打交道更是频繁,由于SQL 不同于与其他编程语言的最明显特征是处理代码的顺序。在大数编程语言中,代码按编码顺序被处理,但是在SQL语言中,第一个被处理的子句是FROM子句,尽管SELECT语句第一个出现,但是几乎总是最后被处理。

每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。这些虚拟表对调用者(客户端应用程序或者外部查询)不可用。只是最后一步生成的表才会返回 给调用者。如果没有在查询中指定某一子句,将跳过相应的步骤。下面是对应用于SQL server 2000和SQL Server 2005的各个逻辑步骤的简单描述。

(8)SELECT (9)DISTINCT (11)<Top Num> <select list>
(1)FROM [left_table]
(3)<join_type> JOIN <right_table>
(2)ON <join_condition>
(4)WHERE <where_condition>
(5)GROUP BY <group_by_list>
(6)WITH <CUBE | RollUP>
(7)HAVING <having_condition>
(10)ORDER BY <order_by_list>

逻辑查询处理阶段简介

FROM:对FROM子句中的前两个表执行笛卡尔积(Cartesian product)(交叉联接),生成虚拟表VT1
ON:对VT1应用ON筛选器。只有那些使<join_condition>为真的行才被插入VT2。
OUTER(JOIN):如 果指定了OUTER JOIN(相对于CROSS JOIN 或(INNER JOIN),保留表(preserved table:左外部联接把左表标记为保留表,右外部联接把右表标记为保留表,完全外部联接把两个表都标记为保留表)中未找到匹配的行将作为外部行添加到 VT2,生成VT3.如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表为止。
WHERE:对VT3应用WHERE筛选器。只有使<where_condition>为true的行才被插入VT4.
GROUP BY:按GROUP BY子句中的列列表对VT4中的行分组,生成VT5.
CUBE|ROLLUP:把超组(Suppergroups)插入VT5,生成VT6.
HAVING:对VT6应用HAVING筛选器。只有使<having_condition>为true的组才会被插入VT7.
SELECT:处理SELECT列表,产生VT8.
DISTINCT:将重复的行从VT8中移除,产生VT9.
ORDER BY:将VT9中的行按ORDER BY 子句中的列列表排序,生成游标(VC10).
TOP:从VC10的开始处选择指定数量或比例的行,生成表VT11,并返回调用者。

注:步骤10,按ORDER BY子句中的列列表排序上步返回的行,返回游标VC10.这一步是第一步也是唯一一步可以使用SELECT列表中的列别名的步骤。这一步不同于其它步骤的 是,它不返回有效的表,而是返回一个游标。SQL是基于集合理论的。集合不会预先对它的行排序,它只是成员的逻辑集合,成员的顺序无关紧要。对表进行排序 的查询可以返回一个对象,包含按特定物理顺序组织的行。ANSI把这种对象称为游标。理解这一步是正确理解SQL的基础。

因为这一步不返回表(而是返回游标),使用了ORDER BY子句的查询不能用作表表达式。表表达式包括:视图、内联表值函数、子查询、派生表和共用表达式。它的结果必须返回给期望得到物理记录的客户端应用程序。例如,下面的派生表查询无效,并产生一个错误:

select *
from(select orderid,customerid from orders order by orderid)
as d

下面的视图也会产生错误

create view my_view
as
select *
from orders
order by orderid

在SQL中,表表达式中不允许使用带有ORDER BY子句的查询,而在T—SQL中却有一个例外(应用TOP选项)。

所以要记住,不要为表中的行假设任何特定的顺序。换句话说,除非你确定要有序行,否则不要指定ORDER BY 子句。排序是需要成本的,SQL Server需要执行有序索引扫描或使用排序运行符。

好了,本教程到此就结束了,相信大家多多少少对SQL语句执行顺序相关内容有所了解了吧,更多知识请登录我们官网了解更多。

(0)

相关推荐

  • SQL语句执行顺序图文介绍

    大家好,我们的数据库已经介绍完了,这里给大家总结一下. 我们这段主要是学习了SQL的增删改查语句,其中查询是我们的重点.我们是以SQL Server 2005来学习的SQL语句,关于SQL Server的图形界面操作,和关于视图.数据库备份还原这些大家下来要下来看一下. 关于Oracle,我们都已经学习了SQL语句,那么Oracle其实已经学习了一大半,就接下来自己学习Oracle主要是看一下他的概念,Oracle和SQL Server还是有很大不同的,熟悉他的表空间这些概念,了解他的图形界面,

  • sql和MySQL的语句执行顺序分析

    今天遇到一个问题就是mysql中insert into 和update以及delete语句中能使用as别名吗?目前还在查看,但是在查阅资料时发现了一些有益的知识,给大家分享一下,就是关于sql以及MySQL语句执行顺序: sql和mysql执行顺序,发现内部机制是一样的.最大区别是在别名的引用上. 一.sql执行顺序 (1)from (2) on (3) join (4) where (5)group by(开始使用select中的别名,后面的语句中都可以使用) (6) avg,sum....

  • SQL语句执行顺序详解

    我们做软件开发的,大部分人都离不开跟数据库打交道,特别是erp开发的,跟数据库打交道更是频繁,由于SQL 不同于与其他编程语言的最明显特征是处理代码的顺序.在大数编程语言中,代码按编码顺序被处理,但是在SQL语言中,第一个被处理的子句是FROM子句,尽管SELECT语句第一个出现,但是几乎总是最后被处理. 每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入.这些虚拟表对调用者(客户端应用程序或者外部查询)不可用.只是最后一步生成的表才会返回 给调用者.如果没有在查询中指定某一子句,将跳过

  • Mysql系列SQL查询语句书写顺序及执行顺序详解

    目录 1.一个完整SQL查询语句的书写顺序 2.一个完整的SQL语句执行顺序 3.关于select和having执行顺序谁前谁后的说明 1.一个完整SQL查询语句的书写顺序 -- "mysql语句编写顺序" 1 select distinct * 2 from 表(或结果集) 3 where - 4 group by -having- 5 order by - 6 limit start,count -- 注:1.2属于最基本语句,必须含有. -- 注:1.2可以与3.4.5.6中任一

  • MySQL执行SQL语句的流程详解

    目录 1.通常sql执行流程 1.1 问题1:MySQL谁去处理网络请求? 1.2 问题2:MySQL如何执行sql语句? 1.3 查询解析器 1.4 查询优化器 1.5 存储引擎 1.6 执行器 2.总结 1.通常sql执行流程 用户发起请求到业务服务器,执行sql语句时,先到连接池中获取连接,然后到mysql服务器执行查询. 1.1 问题1:MySQL谁去处理网络请求? msyql服务器谁负责从这个连接中去监听这个网络请求?谁负责从网络连接里把数据读出来? 其实大家都知道,网络连接必须得分配

  • 对for循环中表达式和循环体的执行顺序详解

    对于学c的朋友来说,for循环可能使我们经常用到的一种循环语句 for(表达式1:表达式2:表达式3){循环体} 知道其的语句执行顺序对我们来说可以避免很多失误 我们可以利用下面这个小程序轻易测出其内在的语句循环顺序: #include<stdio.h> void main() { int i; for (printf("#1\n"),i=1; printf("#2\n"),i<=5; printf("#3\n"),i++) {

  • 对python中的try、except、finally 执行顺序详解

    如下所示: def test1(): try: print('to do stuff') raise Exception('hehe') print('to return in try') return 'try' except Exception: print('process except') print('to return in except') return 'except' finally: print('to return in finally') return 'finally'

  • java异常处理执行顺序详解try catch finally

    目录 不含return的执行顺序 finally子句 含return的执行顺序 返回类型是对象类型时值的变化 结论 不含return的执行顺序 执行顺序为执行try中代码,如果没有异常,然后执行try catch后续的代码.如: public static void main(String[] args) { try { int j = 10 / 2; System.out.println("执行try中代码!"); } catch (Exception e) { e.printSta

  • vue中各选项及钩子函数执行顺序详解

    在vue中,实例选项和钩子函数和{{}}表达式都是不需要手动调用就可以直接执行的. vue的生命周期如下图: 在页面首次加载执行顺序有如下: beforeCreate //在实例初始化之后.创建之前执行 created //实例创建后执行 beforeMounted //在挂载开始之前调用 filters //挂载前加载过滤器 computed //计算属性 directives-bind //只调用一次,在指令第一次绑定到元素时调用 directives-inserted //被绑定元素插入父

  • 基于Laravel 多个中间件的执行顺序详解

    问题 一个路由需要用到多个中间件,其中一个是 Laravel 自带的 auth 中间件. 发现这个中间件不管放在哪里,总是在自定义中间件之前执行. 如果业务需要自定义中间在 auth 之前执行,还是有办法的. 解决方案 观察定义中间件的 app\Http\Kernel 类,是继承的 Illuminate\Foundation\Http\Kernel 类. 再打开 Illuminate\Foundation\Http\Kernel ,发现有这样一个数组 ... /** * The priority

  • vue中created、watch和computed的执行顺序详解

    目录 前言 为什么? 1.关于initComputed 2.关于initWatch 总结 前言 面试题:vue中created.watch(immediate: true)和computed的执行顺序是啥? 先看个简单的例子: // main.js import Vue from "vue"; new Vue({ el: "#app", template: `<div> <div>{{computedCount}}</div> &

  • java面试题之try中含return语句时代码的执行顺序详解

    前言 最近在刷java面试题偶然看到这类问题(try/finally中含有return时的执行顺序),觉得挺有意思于是小小的研究了一下,希望经过我添油加醋天马行空之后,能给你带来一定的帮助,下面来看看详细的介绍. 原题 try {} 里有一个return语句,那么紧跟在这个try后的finally {}里的代码会不会被执行?什么时候被执行?在return前还是后? 乍一看题目很简单嘛,java规范都说了,finally会在try代码块的return之前执行,你这文章写得没意义,不看了 你等等!(

随机推荐