sql的执行顺序,是优化sql语句执行效率必须要掌握的。各个数据库可能有细小的差别,但大体顺序是相同的,这里只做大致说明。

一、总体执行顺序

  在sql语句执行之前,还有SQL语句准备执行阶段,这里不做描述,只介绍sql语句执行顺序。

  这是一个完整的查询语句的执行顺序,可见sql语句并不是顺序执行的。每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。这些虚拟表对调用者不可用,只在最后一步生成的表才会返回给调用者。

(7)     SELECT
(8) DISTINCT <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) HAVING <having_condition>
(9) ORDER BY <order_by_condition>
(10) LIMIT <limit_number>

二、每个步骤的执行顺序

  知道总体上的执行顺序并不能帮助优化sql语句,因为这些子句的执行顺序你是不能改的,所以必须要知道在每个子句中的执行顺序。

1)执行from子句

  对FROM子句中的前两个表执行笛卡尔积,生成虚拟表VT1。

2)执行on子句

  对VT1应用ON筛选器,按join_condition条件过滤,去掉那些不符合条件的数据,得到VT2表。

3)OUTER(JOIN)添加外部行 

  这一步只有在连接类型为OUTER JOIN时才发生,如LEFT OUTER JOINRIGHT OUTER JOIN和FULL OUTER JOIN。大多数时候我们都是会省略掉OUTER关键字的,但OUTER表示的就是外部行。

  LEFT OUTER JOIN把左表记为保留表;RIGHT OUTER JOIN把右表记为保留表;FULL OUTER JOIN把左右表都作为保留表。

  如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表为止。

  添加外部行的工作就是在VT2表的基础上添加保留表中被过滤条件过滤掉的数据,非保留表中的数据被赋予NULL值,最后生成虚拟表VT3。

4)执行WHERE过滤

  对添加外部行得到的VT3进行WHERE过滤,只有符合<where_condition>的记录才会输出到虚拟表VT4中。

  采用自下而上从右到左的顺序解析Where 子句,根据这个原理,表之间的连接必须写在其他Where 条件之前, 可以过滤掉最大数量记录的条件最好写在Where 子句的末尾。

5)执行GROUP BY分组

  对使用where子句得到的虚拟表进行分组操作,得到的内容会存入虚拟表VT5中。

  要提高GROUP BY 语句的效率, 可以将不需要的记录在GROUP BY 之前过滤掉。即在GROUP BY前使用WHERE来过虑,尽量避免GROUP BY后再HAVING过滤。

6)执行HAVING过滤

  HAVING子句主要和GROUP BY子句配合使用,对分组得到的VT5虚拟表进行条件过滤,得到VT6。应该避免使用HAVING 子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作。

7)SELECT列表

  从虚拟表VT6中选择出我们需要的内容,得到VT7。

  注意少用*号,尽量取字段名称,因为ORACLE 在解析的过程中, 会依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 使用列名意味着将减少消耗时间。

8)执行DISTINCT子句

  创建一张内存临时表(如果内存放不下,就需要存放在硬盘了)。这张临时表的表结构和上一步产生的虚拟表VT7是一样的,不同的是对进行DISTINCT操作的列增加了一个唯一索引,以此来除重复数据。

9)执行ORDER BY子句

  对虚拟表中的内容按照指定的列进行排序,然后返回一个新的虚拟表。结果存储在VT8中。

  执行顺序为从左到右排序,很耗资源。

10)执行LIMIT子句

  LIMIT子句从上一步得到的VT8虚拟表中选出从指定位置开始的指定行数据。对于没有应用ORDER BY的LIMIT子句,得到的结果同样是无序的,所以很多时候都会看到LIMIT子句会和ORDER BY子句一起使用。

sql执行顺序整理的更多相关文章

  1. SQLSERVER 2008 技术内幕 T-SQL查询 笔记1: SQL 执行顺序

    与大多数语言一样,SQL语言也有一个执行顺序,只是在大多数编程语言中,代码是按照编写顺序来处理的,而在SQL中则不是,下图为SQL 执行顺序. () ) [ ALL | DISTINCT ] () [ ...

  2. 获取分组后统计数量最多的纪录;limit用法;sql执行顺序

    CREATE TABLE emp(id INT PRIMARY KEY,NAME VARCHAR(11),dep_id INT ,salary INT); CREATE TABLE dept(id I ...

  3. 0708关于理解mysql SQL执行顺序

    转自 http://www.jellythink.com/archives/924,博客比价清晰 我理解上文的是SQL执行顺序 总体方案.当你加入索引了以后,其实他的执行计划是有细微的变化,比方说刚开 ...

  4. MySQL中的索引、左连接、右连接、join、sql执行顺序

    逻辑架构: 1.连接层 2.服务层 3.引擎层(插拔式) 4.存储层 存储引擎: 常用的有:MyISAM.InnoDB 查看命令:show variables like '%storage_engin ...

  5. 初识SQL 执行顺序

    SQL不同于一般的程序代码,会按照一定的顺序进行执行,他的第一个执行始终从from开始执行,虽然Select出现在第一位置但是执行顺序 确不是在第一个.有时候可能大家写了很久的代码,不一定能够很好的理 ...

  6. [整]SQL执行顺序

    SQL的执行顺序: 第一步:FROM <left_table> <join_type> JOIN <right_table> ON <on_predicate ...

  7. SQL 执行顺序

    SQL 是一种声明式语言,与其他语言相比它的最大特点是执行顺序-并非按照语法顺序来执行.因此很多程序猿看到SQL就头疼,我之前也是这样,后来看到一篇文章后豁然开朗-地址. 理解了SQL的执行顺序无疑对 ...

  8. mysql sql执行顺序

    <pre name="code" class="html">mysql> explain select * from (select * fr ...

  9. [SQL]SQL 执行顺序

    这个文章主要是防止我忘了 SQL 的执行顺序,解释的东西我都没怎么看懂.数据库渣如我- 逻辑查询处理阶段简介 FROM:对FROM子句中的前两个表执行笛卡尔积(Cartesian product)(交 ...

随机推荐

  1. <微信应用开发系列>定时刷新AccessToken

    微信内嵌H5站一直很火,很多公司也想借助微信的用户群和社交群来做点事情,所以对于各位代码君来说也算是一个研究方向吧. access_token是公众号的全局唯一票据,公众号调用各接口时都需使用acce ...

  2. Web项目去掉Js文件红叉

    项目用到jquery,但将Jquery拷进去后,js文件有个红叉,看上去非常不爽.如下图: 解决方法: 1.找到项目下的.project文件 2.去掉Javascript验证 <?xml ver ...

  3. javascript实现倒计时程序

    最近在网上看到一道这样的面试题: 题:  网页中实现一个计算当年还剩多少时间的倒数计时程序,要求网页上实时动态显示“××年还剩××天××时××分××秒”? 我实现了,发现挺有意思,下面把我的代码贴出来 ...

  4. Windows命令行(DOS命令)教程-7 (转载)http://arch.pconline.com.cn//pcedu/rookie/basic/10111/15325_6.html

    11. deltree [功能] 删除目录树 [格式] [C:][path]DELTREE [C1:][path1] [[C2:][path2] […]] [说明] 这个命令将整个指定目录树全部消灭, ...

  5. java HashMap的原理

    HashMap的数据结构: 在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外.HashMap实际 ...

  6. .net 2.0中半角全角错误的解决办法

    VS2005中.net 2.0编译报错如下所示:'System.Windows.Forms.ImeMode' does not contain a definition for 'OnHalf'.只需 ...

  7. NSDictionary使用小结

    http://blog.csdn.net/ms2146/article/details/8656787

  8. 分布式Session共享(一):tomcat+redis实现session共享

    一.前言 本文主要测试redis实现session共享的实现方式,不讨论如何让nginx参与实现负载均衡等. 二.环境配置 本测试在Window下进行 name version port Tomcat ...

  9. 在msvc中使用Boost.Spirit.X3

    Preface “Examples of designs that meet most of the criteria for "goodness" (easy to unders ...

  10. 慕课linux学习笔记(五)常用命令(2)

    链接命令 Ln [原文件] [目标文件] -s 表示创建软链接 硬链接特征: 拥有相同的i节点和存储block块,可以看做是同一个文件 通过i节点识别 不能跨分区 不能针对目录用 软链接特征: 不同的 ...