带leftjoin的sql的执⾏顺序
1.笛卡尔积(Cartesian product)
顾名思义, 这个概念得名于笛卡⼉. 在数学中,两个集合 X 和 Y 的笛卡⼉积(Cartesian product),⼜称直积,表⽰为 X × Y,是其第⼀个对象是 X 的成员⽽第⼆个对象是 Y 的⼀个成员的所有可能的有序对.
假设A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)}。可以扩展到多个集合的情况。类似的例⼦有,如果A表⽰某学校学⽣的集合,B表⽰该学校所有课程的集合,则A与B的笛卡尔积表⽰所有可能的选课情况。
2.Join类型
cross join 是笛卡⼉乘积就是⼀张表的⾏数乘以另⼀张表的⾏数.
inner join 只返回两张表连接列的匹配项.
left join 第⼀张表的连接列在第⼆张表中没有匹配是,第⼆张表中的值返回null.
right join 第⼆张表的连接列在第⼀张表中没有匹配是,第⼀张表中的值返回null.
full join 返回两张表中的⾏ left join+right join.
3.在对两表进⾏各种类型的join (cross, left, right, full, inner)时, 都需要构造笛卡尔积.
有时想想不可思议, 若两个特⼤表进⾏join, 难道sql就直接上笛卡尔积吗? 难道不事前进⾏on的条件过滤吗? 那数据量得多⼤?
4.查⼀下MSDN就清楚了整个SQL的执⾏顺序.
Processing Order of the SELECT statement
The following steps show the processing order for a SELECT statement.
1.FROM
2.ON
3.JOIN
4.WHERE
5.GROUP BY
6.WITH CUBE or WITH ROLLUPjoin和in哪个查询更快
7.HAVING
8.SELECT
9.DISTINCT
10.ORDER BY
11.TOP
也就是说, 先进⾏on的过滤, ⽽后才进⾏join, 这样就避免了两个⼤表产⽣全部数据的笛卡尔积的庞⼤数据.
这些步骤执⾏时, 每个步骤都会产⽣⼀个虚拟表,该虚拟表被⽤作下⼀个步骤的输⼊。这些虚拟表对调⽤者(客户端应⽤程序或者外部查询)不可⽤。只是最后⼀步⽣成的表才会返回给调⽤者。
如果没有在查询中指定某⼀⼦句,将跳过相应的步骤。
下⾯是<<Inside Microsoft SQL Server 2008 T-SQL Querying>>⼀书中给的⼀幅SQL 执⾏顺序的插图.
5.On的其余过滤条件放Where⾥效率更⾼还是更低?
select * from table1 as a
inner join table2 as b on a.id=b.id and a.status=1
select * from table1 as a
inner join table2 as b on a.id=b.id
where a.status=1
查查MSDN就清楚了.
There can be predicates that involve only one of the joined tables in the ON clause. Such predicates also can be in the WHERE clause in the query. Although the placement of such predicates does not make a difference for INNER joins, they might cause a different result when OUTER joins are involved. This is because the predicates in the ON clause are applied to the table before the join, whereas the WHERE clause is semantically applied to the result of the join.
翻译之后是, 如果是inner join, 放on和放where产⽣的结果⼀样, 但没说哪个效率速度更⾼? 如果有outer join (left or right), 就有区别了, 因为on⽣效在先, 已经提前过滤了⼀部分数据, ⽽where⽣效在后.
综合⼀下, 感觉还是放在on⾥更有效率, 因为它先于where执⾏.
听说可以通过sql的查询计划来判别实际的结果, 明天再研究, 欢迎⾼⼿给与批评指正.
********************************************************************************************************
2011/11/21 最新体会
刚看到<<Microsoft SQL Server 2008技术内幕: T-SQL查询>>⼀书中对于连接的描述和我先前理解的不太⼀样;
Itzib在书上说先笛卡尔积, 然后再on过滤, 如果join是inner的, 就继续往下⾛, 如果join 是left join, 就把on过滤掉的左主表中的数据再添加回来; 然后再执⾏where⾥的过滤;
on中不是最终过滤, 因为后⾯left join还可能添加回来, ⽽where才是最终过滤.
只有当使⽤外连接(left, right)时, on 和 where 才有这个区别, 如果⽤inner join, 在哪⾥制定都⼀样, 因为on 之后就是where, 中间没有其它步骤.

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。