• select语句关键字的定义的顺序、执行顺序on为什么比where先执行?


    大家都这么说:select语句关键字的定义的顺序、执行顺序:

    (7)SELECT

    (8) DISTINCT

    (11) <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_list>

    (10) LIMIT <limit_number>

    引自:https://blog.csdn.net/qq_40144494/article/details/122836397:

    select各个阶级分别干了什么:

    (1)FROM 阶段

    FROM阶段标识出查询的来源表,并处理表运算符。在涉及到联接运算的查询中(各种join),主要有以下几个步骤:

    a.求笛卡尔积。不论是什么类型的联接运算,首先都是执行交叉连接(cross join),求笛卡儿积,生成虚拟表VT1-J1。

    b.ON筛选器。这个阶段对上个步骤生成的VT1-J1进行筛选,根据ON子句中出现的谓词进行筛选,让谓词取值为true的行通过了考验,插入到VT1-J2。

    c.添加外部行。如果指定了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。这个步骤一般按下列顺序进行

    a.计算SELECT列表中的表达式,生成VT5-1。

    b.若有DISTINCT,则删除VT5-1中的重复行,生成VT5-2

    c.若有TOP,则根据ORDER BY子句定义的逻辑顺序,从VT5-2中选择签名指定数量或者百分比的行,生成VT5-3

    (6)ORDER BY阶段

    根据ORDER BY子句中指定的列明列表,对VT5-3中的行,进行排序,生成游标VC6.

    那么为什么on先执行呢?

    是否可以这么理解:

    代码实现上是先构建逻辑,确实是这样实现的,以hash join来说:先要构建hash join的循环逻辑,然后再扫描小表用where去掉不符合条件的行,构建哈希表,然后以大表驱动去做hash运算;最后根据left、right join来构造虚拟列。

    实际执行:是需要先进行扫描from,获取满足条件的行where、然后进行join计算。

    on、where、having 区别以及顺序

    on、where、having这三个都可以加条件的子句中,on是最先执行,where次之,having最后。有时候如果这先后顺序不影响中间结果的话,那最终结果是相同的。但因为on是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的。   

    根据上面的分析,可以知道where也应该比having快点的,因为它过滤数据后才进行sum,所以having是最慢的。但也不是说having没用,因为有时在步骤3还没出来都不知道那个记录才符合要求时,就要用having了。   

    在两个表联接时才用on的,所以在一个表的时候,就剩下where跟having比较了。在这单表查询统计的情况下,如果要过滤的条件没有涉及到要计算字段,那它们的结果是一样的,只是where可以使用rushmore技术,而having就不能,在速度上后者要慢。   

    如果要涉及到计算的字段,就表示在没计算之前,这个字段的值是不确定的,根据上篇写的工作流程,where的作用时间是在计算之前就完成的,而having就是在计算后才起作用的,所以在这种情况下,两者的结果会不同。   

    在多表联接查询时,on比where更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where进行过滤,然后再计算,计算完后再由having进行过滤。由此可见,要想过滤条件起到正确的作用,首先要明白这个条件应该在什么时候起作用,然后再决定放在那里。

    Ps:JOIN联表中ON、WHERE后面跟条件的区别对于JOIN的连表操作,这里就不细述了,当我们在对表进行JOIN关联操作时,对于ON和WHERE后面的条件,不清楚大家有没有注意过,有什么区别,可能有的朋友会认为跟在它们后面的条件是一样的,你可以跟在ON后面,如果愿意,也可以跟在WHERE后面。它们在ON和WHERE后面究竟有一个什么样的区别呢?

    对于JOIN参与的表的关联操作,如果需要不满足连接条件的行也在我们的查询范围内的话,我们就必需把连接条件放在ON后面,而不能放在WHERE后面,如果我们把连接条件放在了WHERE后面,那么所有的LEFT、RIGHT,等这些操作将不起任何作用,对于这种情况,它的效果就完全等同于INNER连接。对于那些不影响选择行的条件,放在ON或者WHERE后面就可以。

    记住:所有的连接条件都必需要放在ON后面,不然前面的所有 LEFT 和 RIGHT 关联将作为摆设,而不起任何作用。

    http://t.zoukankan.com/jacky912-p-10320557.html

    https://blog.csdn.net/sanyaoxu_2/article/details/97916382?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-97916382-blog-122836397.pc_relevant_default&spm=1001.2101.3001.4242.1&utm_relevant_index=3

    https://www.cnblogs.com/howhy/p/6214992.html

    https://blog.csdn.net/qq_40144494/article/details/122836397

    --待续

  • 相关阅读:
    selenium Grid2 分布式自动化测试环境搭建
    Python Appium 开启Android测试之路
    C#导出数据到CSV和EXCEL文件时数字文本被转义的解决方法
    浅谈 DML、DDL、DCL的区别
    让EntityFramework6支持SQLite
    System.Drawing.Color的颜色对照表
    清除远程桌面连接记录和SQLSERVER 连接记录的办法
    Jquery操作select选项集合!
    asp.net 模拟CURL调用微信公共平台API 上传下载多媒体文件接口
    Log4net 根据日志类别保存到不同的文件,并按照日期生成不同文件名称
  • 原文地址:https://www.cnblogs.com/kuang17/p/16444419.html
Copyright © 2020-2023  润新知