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. ThinkPHP3.2.3中三大自动中的缺陷问题

    我们在使用Thinkphp3.2.3框架时在对数据表进行模型化后就可以使用自动完成功能. 自动完成可以帮助我们更简便的完成对表单内容对数据表(集合)的填充,自动完成是基于: 当实例化数据库user后, ...

  2. hdu 4756 Install Air Conditioning

    非正规做法,一个一个的暴,减一下枝,还得采用sort,qsort居然过不了…… #include <cstdio> #include <cmath> #include < ...

  3. linux高级技巧:heartbeat+lvs(一)

    1.heartbeat一个简短的引论:        Heartbeat 项目是 Linux-HA project的一个组成部分,它实现了一个高可用集群系统.心跳服务和集群通信是高可用集群的两个关键组 ...

  4. My way on Linux - [虚拟化&云计算] - 云计算概述&KVM虚拟化基础

    思维导图

  5. 超长英文(代码)自动换行的样式(CSS)

    如何想让一连串文字在显示可以自动换行,而不会把在代码中使用的容器撑开,则在文章的CSS样式处加上以下代码即可: table-layout: fixed; word-wrap:break-word;或者 ...

  6. Microsoft Visual Studio 产品密钥

    Microsoft Visual Studio 2010 产品密钥:YCFHQ-9DWCY-DKV88-T2TMH-G7BHP Microsoft Visual Studio 2013 产品密钥:BW ...

  7. oracle学习笔记(一)用户管理

    --oracle学习第一天 --连接 @后面连接数据库实例,具体连接到那个数据库 conn scott/tiger@MYORA1; --修改密码 passw; --显示用户 show user; -- ...

  8. Private Members in JavaScript

    Private Members in JavaScript Douglas Crockford www.crockford.com JavaScript is the world's most mis ...

  9. js中的因数分解

    方法一: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8& ...

  10. 7 RandomAccessFile读取文件内容保存--简单例子(需要验证)

    import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; /** * 读取动态产生的文件内容 */ publ ...