SQL语句到底是怎么执行的
写在前面的话:有时不理解SQL语句各个部分执行顺序,导致理解上出现偏差,或者是书写SQL语句时随心所欲,所以有必要了解一下sql语句的执行顺序。可以有时间自己写一个简单的数据库,理解会更加深入。下面就写写我的一些理解,以SQL SERVER2008为例,进行说明。
先看下面这条简单SQL语句:
select * from Student
这条SQL语句是否可以有下面两种理解呢
(1)先从Student表中选出age>20的数据,然后从这些数据中选择前面的10条数据。
(2)先从Student表中选出前10条数据,然后从这些数据中选择age>20的数据。
那么到底哪个是正确的呢?你可能会说,这还不容易,肯定是(1)是正确的。没错,对于这样的简单的语句,一眼就能看出来,可是对于稍微复杂一些的SQL语句或者更加复杂的SQL语句,有时我们一眼就看不出来了,为了能够正确分析SQL语句以及写出正确的SQL语句,有必要了解一下SQL语句各部分的执行顺序。
好了,我们再看下面的一条SQL语句:
select distinct Table1.id,COUNT(Table1.name) as nameCount from Table1 inner join Table2 on Table1.id=Table2.id group by Table1.id order by Table1.id desc
其中Table1和Table2就是我随便建立的两个非常简单的表,为了讲解方便,我也没有弄一些跟实际相结合的表,要不还要理解业务逻辑,干脆越简单越好,毕竟目的是为了说明SQL语句的执行顺序,Table1和Table2如下:
 
    
Table1 Table2
下面先给出上面的SQL语句的执行顺序,然后进行讲解:
(8) select (9) distinct (6) Table1.id,COUNT(Table1.name) as nameCount (1) from Table1 (3) inner join Table2 (2) on Table1.id=Table2.id (5) group by Table1.id (10) order by Table1.id desc
红色序号给出了执行的顺序:
(1)from:对Table1和Table2执行笛卡尔积,也就是两个表的行的各种组合,共5*5=25行,生成虚拟表VT1
(2)on:选择VT1中的那些Table1.id=Table2.id的所有行,生成虚拟表VT2。
(3)inner join:这里是内部连接,直接就是VT2,如果是outer join,如left join、right join、full join,那么还需要按照外部连接的规则,把VT1中没有匹配的行添加到VT2,生成VT3.
(4)where:选出VT3中Table1.id<4的表格,给虚拟表VT4.
(5)group by:按照Table1.id进行分组。
(6)COUNT:执行聚合函数,选出对应Table1.id的行数,生成的结果给虚拟表VT5
(7)having:选择VT5中Table1.id<3的所有结果,给虚拟表VT6
(8)select:选择VT6中相应的列,给虚拟表VT7
(9)distinct:将VT7中重复的行去除,生成VT8
(10)order by:将VT8的结果按照Table1.id进行排序,这里没有生成一个新的表VT9,而是生成游标VC9。
(11)top:从游标VC9的开始处选择指定的行数,这里是1行,生成虚拟表VT10.
经过上面的过程,最终的SQL语句将VT10返回给用户使用。
所以以后再写SQL语句的时候,可以按照上面的顺序写SQL语句了,读SQL语句也可以按照上面的顺序去读,做到心里明白。
好了,啰啰嗦嗦说了这么多,上个图吧(真是奇丑无比),一图胜千言,自己做个总结,也希望对大家有所帮助。

(完)
文档信息
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
- 本文为原创文章,欢迎转载,后续本博客会不断更新,因此请保留该文档信息。
- 本文地址:http://www.cnblogs.com/wuguanglei/p/4198272.html
SQL语句到底是怎么执行的的更多相关文章
- SQL 语句在查询分析器执行很快,程序 Dapper 参数化查询就很慢(parameter-sniffing)
		这个问题困扰我好长时间了,使用SQLSERVER 事务探查器找到执行超时的SQL语句,参数查询都是通过执行exe sp_executesql 的存储过程调用,因为它能够分析并缓存查询计划,从而优化查询 ... 
- [sqlserver脚本]查看指定SQL语句生成了哪些执行计划
		参考SQL技术内幕写了一段脚本,可以通过这段脚本查看执行指定SQL语句后,系统生成了哪些执行计划.使用时注意以下几点: 修改use MyTest,换成自己的数据库名字. 将 exec sp_page_ ... 
- 【mybatis】mybatis执行一个update方法,返回值为1,但是数据库中数据并未更新,粘贴sql语句直接在数据库执行,等待好久报错:Lock wait timeout exceeded; try restarting transaction
		今天使用mybatis和jpa的过程中,发现这样一个问题: mybatis执行一个update方法,返回值为1,但是数据库中数据并未更新,粘贴sql语句直接在数据库执行,等待好久报错:Lock wai ... 
- 009 面试题 SQL语句各部分的执行顺序
		SQL语句各部分的执行顺序 select distinct...from t1 (left/right) join t2 on t1.xx=t2.xx where t1.xx=? and t2.xx= ... 
- 如何测试sql语句性能,提高执行效率
		有时候我们经常为我们的sql语句执行效率低下发愁,反复优化后,可还是得不到提高 那么你就用这条语句找出你sql到底是在哪里慢了 示例: SET STATISTICS io ON SET ... 
- SQL 语句与性能之执行顺序
		select * , t3.Name from t1 left join t2 on t1.sysno = t2.Asysno left join t3 on t3.sysno = t2.Bsysno ... 
- 普通SQL语句可以用Exec执行
		例如存储过名为:myprocedure use AdventureWorks create procedure myprocedure @city varchar(20) as begin selec ... 
- SqlServer 中如何查看某一个Sql语句是复用了执行计划,还是重新生成了执行计划
		我们知道SqlServer的查询优化器会将所执行的Sql语句的执行计划作缓存,如果后续查询可以复用缓存中的执行计划,那么SqlServer就会为后续查询复用执行计划而不是重新生成一个新的执行计划,因为 ... 
- 很好的复习资料: SQL语句到底怎么写 ?
		本文用到的数据库如下: CREATE DATABASE exam; /*创建部门表*/ CREATE TABLE dept( deptno INT PRIMARY KEY, dname VARCHAR ... 
随机推荐
- mysql salve从库设置read only 属性
			在MySQL数据库中,在进行数据迁移和从库只读状态设置时,都会涉及到只读状态和Master-slave的设置和关系. 经过实际测试,对于MySQL单实例数据库和master库,如果需要设置为只 ... 
- UWP Composition API - GroupListView(一)
			需求: 光看标题大家肯定不知道是什么东西,先上效果图: 这不就是ListView的Group效果吗?? 看上去是的.但是请听完需求.1.Group中的集合需要支持增量加载ISupportIncreme ... 
- CPPFormatLibary提升效率的优化原理
			CPPFormatLibary,以下简称FL,介绍:关于CPPFormatLibary. 与stringstream,甚至C库的sprintf系列想比,FL在速度上都有优势,而且是在支持.net格式化 ... 
- 标准io与文件io
			A: 代码重复: 语句块1: while(判断) { 语句块2: 语句块1: } 上面可以改写为: while(1) { 语句块1: if(判断) break: 语句块2: } B: 标准IO和文件I ... 
- delphi 步长不等于 1 的方法
			i:=; do begin ... INC(i,); end; 不能用for循环,只能用像上面的方法折衷一下 
- 微信禁用右上角的分享按钮,WeixinJSBridge API以及隐藏分享的子按钮等菜单项
			<!--禁用微信分享按钮--> <script> function onBridgeReady() { WeixinJSBridge.call('hideOptionMenu' ... 
- JQUERY UI Datepicker Demo
			datepicker_demo.htm <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" &quo ... 
- SilverLight抛出 System.InvalidOperationException: 超出了2083 的最大URI
			在SilverLight中对于抛出 System.InvalidOperationException: 超出了 2083 的最大 URI 长度 的异常 处理 其实很简单 在 EntityFramewo ... 
- 【BZOJ2073】[POI2004]PRZ 状压DP
			[BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ... 
- liunux 修改hostname
			最近鼓捣Oracle,记录些技巧 修改hostname # vim /ect/hosts # vim /etc/sysconfig/network 修改hostname # service netwo ... 
