1. join中相比where优先推荐on
WHERE子句中使用的连接语句,在数据库语言中,被称为
隐性连接。INNER JOIN……ON子句产生的连接称为
显性连接。(其他JOIN参数也是显性连接)WHERE和INNER JOIN产生的连接关系,没有本质区别,结果也一样。但是!隐性连接随着数据库语言的规范和发展,已经逐渐被淘汰,比较新的数据库语言基本上已经抛弃了隐性连接,全部采用显性连接了。
无论怎么连接,都可以用join子句,但是连接同一个表的时候,注意要定义别名,否则产生错误!
参考:
http://blog.sina.com.cn/s/blog_54cd1aa30100plmx.html
2. 逻辑上一个query的执行顺序(不是实际)
1. FROM
2. ON
3. JOIN
4. WHERE
5. GROUP BY
6. WITH CUBE or WITH ROLLUP
7. HAVING
8. SELECT
9. DISTINCT
10. ORDER BY
11. TOP
说是“逻辑上” 顺序,因为实际执行时还要看索引,数据分布等,看最终优化器如何处理,最真实的顺序肯定是执行计划展示的顺序。
下面这段参考:
http://www.phpddt.com/db/join-on-where.html
引用
SQL语句中join连表时on和where后都可以跟条件,那么对查询结果集,执行顺序,效率是如何呢?
通过查询资料发现:
区别:
on是对中间结果进行筛选,where是对最终结果筛选。
执行顺序:
先进行on的过滤, 而后才进行join。
效率:
如果是inner join, 放on和放where产生的结果一样, 但没说哪个效率速度更高? 如果有outer join (left or right), 就有区别了, 因为on生效在先, 已经提前过滤了一部分数据, 而where生效在后.
最后来了解下T-SQL对查询逻辑处理。
T-SQL逻辑查询的各个阶段(编号代表顺序):
(5)SELECT DISTINCT TOP(<top_specification>) <select_list>
(1)FROM <left_table> <join_type> JOIN <right_table> ON <on_predicate>
(2)WHERE <where_predicate>
(3)GROUP BY <group_by_specification>
(4)HAVING <having_predicate>
(6)ORDER BY <order_by_list>
T-SQL在查询各个阶级分别干了什么:
(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.
如果是inner join, 放on和放where产生的结果一样, 执行计划也是一样,
但推荐使用on。但如果有outer join (left or right), 就有区别了, 因为on生效在先, 已经提前过滤了一部分数据, 而where生效在后,而且on对于outer join有不生效的情况,需要看and条件是作用在左表还是右表:
http://www.cnblogs.com/hgwy/articles/1691689.html
参考:
http://www.phpddt.com/db/join-on-where.html
http://dba.stackexchange.com/questions/5038/sql-server-join-where-processing-order
http://blog.chinaunix.net/uid-27570589-id-3771152.html
这篇
http://coolshell.cn/articles/3463.html也提到:
引用
如果不是使用嵌套的select语句,一般系统都会产生笛卡尔乘积然再做过滤。这是对于性能来说是非常危险的,尤其是表很大的时候。
3. merge join, hash join, nested join
很好的一篇文章:
https://msdn.microsoft.com/zh-cn/library/dn144699.aspx
分享到:
相关推荐
ibatis标签提示工具 sql-map-2.dtd
1、 on条件是在成临时表时使的条件,它不管on中的条件是否为真,都 2、where条件是在临时表成好后,再对临时表进过滤的条件 1、中间表 2、再对中间表过滤
left_join_on_and与left_join_on_where的区别
SQL学习八-LEFT JOIN && RIGHT JOIN
本文简单描述了sql语句join中on和where的区别以及其原理
Getting-Started-with-SQL-A-Hands-On-Approach-for-Beginners.pdf
sql server T-SQl基础教程 源码和示例数据库
17. 基础-SQL-DQL-执行顺序 18. 基础-SQL-DCL-用户管理- 19. 基础-SQL-DCL-权限控制- 20. 基础-函数-字符串函数 21. 基础-函数-数值函数 22. 基础-函数-日期函数 23. 基础-函数-流程函数 24. 基础-约束-概述 25. ...
flume-ng-sql-source-1.5.2.jar从数据库中增量读取数据到hdfs中的jar包
sql-map-config-2.dtd ibats的dtd文件
spark-sql sql on yarn --deploy-mode cluster 改造为 可以cluster提交
SQL学习七-JOIN中的SQL
sqlserver数据库连接驱动包 sqljdbc4-4.0.jar,摘要必须大于50个字节!
azkaban-sql-script-2.5.0.tar.gz
, 首先教你SQL整体优化、快速优化实施、如何读懂执行计划、如何左右执行计划这四大必杀招。整这些干嘛呢?答案是,传授一个先整体后局部的宏观解决思路,走进“道”的世界。, 接下来带领大家飞翔在“术”的天空。教...
当同时出现了where_group_by_having_order_by的时候_执行顺序和编写顺序时的用法
手把手教你写 SQL Join 联接 手把手教你写 SQL Join 联接 - Defonds 的专栏 - CSDN博客手把手教你写 SQL Join 联接 - Defonds 的专栏 - CSDN博客
SQL引擎构建
Join on/inner join on/full join on/full outer join on/left join on/right join on/cross join on; 在使用jion时,on和where条件的区别;
SQL基础教程-表的连接(Oracle)