SQL Server数据库中left outer join与inner join 混用自动优化
沉沙 2018-05-09 来源 : 阅读 1765 评论 0

摘要:left outer join和inner join是两种不同的逻辑操作,单纯的操作可能会产生不同的结果集,但是当这两个操作叠加在一起的时候, SQL Server考虑到结果集是一样。本文主要讲解SQL Server数据库中left outer join与inner join 混用时,SQL Server数据库自动优化执行计划的示例。

以下为示例代码: 

set statistics profile off
DECLARE @t TABLE(id1 INT,c VARCHAR(10))
INSERT INTO @t VALUES(1,'ab')INSERT INTO @t VALUES(2,'abc')INSERT INTO @t VALUES(3,'abcd')INSERT INTO @t VALUES(4,'abcde')
DECLARE @tt TABLE(id1 INT,c VARCHAR(10))
INSERT INTO @tt VALUES(9,'s1')INSERT INTO @tt VALUES(2,'s2')INSERT INTO @tt VALUES(3,'s3')INSERT INTO @tt VALUES(5,'s4')
DECLARE @ttt TABLE(id1 INT,c VARCHAR(10))
INSERT INTO @ttt VALUES(2,'r2')INSERT INTO @ttt VALUES(3,'r3')INSERT INTO @ttt VALUES(6,'r2')INSERT INTO @ttt VALUES(8,'r1')
set statistics profile on
SELECT *FROM @t t left JOIN @tt tt
        ON t.id1 = tt.id1inner JOIN @ttt ttt
        ON t.id1 = ttt.id1

产生了如下的执行计划:

SELECT *  FROM @t t   left JOIN @tt tt          ON t.id1 = tt.id1  inner JOIN @ttt ttt          ON t.id1 = ttt.id1
  |--Nested Loops(Left Outer Join, WHERE:(@t.[id1] as [t].[id1]=@tt.[id1] as [tt].[id1]))
       |--Hash Match(Inner Join, HASH:([ttt].[id1])=([t].[id1]), RESIDUAL:(@t.[id1] as [t].[id1]=@ttt.[id1] as [ttt].[id1]))
       |    |--Table Scan(OBJECT:(@ttt AS [ttt]))
       |    |--Table Scan(OBJECT:(@t AS [t]))
       |--Table Scan(OBJECT:(@tt AS [tt]))

 

这里会先把@t与@ttt进行inner join,这里SQL Server自动优化了连接顺序,先进行inner join可能会产生更小的结果集,然后把结果与@tt 进行 left outer join。

 

把上面最后的sql语句改为:

SELECT *FROM @t t left JOIN @tt tt
        ON t.id1 = tt.id1inner JOIN @ttt ttt
        ON tt.id1 = ttt.id1


执行计划为:

SELECT *  FROM @t t   left JOIN @tt tt          ON t.id1 = tt.id1  inner JOIN @ttt ttt          ON tt.id1 = ttt.id1
  |--Hash Match(Inner Join, HASH:([ttt].[id1])=([tt].[id1]), RESIDUAL:(@tt.[id1] as [tt].[id1]=@ttt.[id1] as [ttt].[id1]))
       |--Table Scan(OBJECT:(@ttt AS [ttt]))
       |--Hash Match(Inner Join, HASH:([t].[id1])=([tt].[id1]), RESIDUAL:(@t.[id1] as [t].[id1]=@tt.[id1] as [tt].[id1]))
            |--Table Scan(OBJECT:(@t AS [t]))
            |--Table Scan(OBJECT:(@tt AS [tt]))


发现内部,@t与@tt进行inner join,然后@ttt与上述结果进行inner join,操作都成了inner join。

为什么呢?我原来想,应该先是@t与@tt进行left join呀,怎么是inner join,仔细想想整个操作是这样的,@t与@tt进行left join,产生了如下结果集:

@t.id1 @tt.id1

1           null

2           2

3           3

4           null

然后再把这个结果和@ttt进行 inner join,连接条件是 @tt.id1 = @ttt.id1,那么这样最后结果一定会把@tt.id1为null的记录给过滤掉了,所以结果只会出来两条。这样的结果,与一开始@t与@tt就进行inner join是一样的,换句话说结果取决于后面的inner join。

left outer join和inner join是两种不同的逻辑操作,单纯的操作可能会产生不同的结果集,但是当这两个操作叠加在一起的时候, SQL Server考虑到结果集是一样,所以优化了表的连接顺序和逻辑操作,目的当然是为了提高效率。

以上就是职坐标整理发布关于left outer join与inner join 混用的介绍,先祝大家应该对它有了一定的了解,希望这篇文章对大家有一定的帮助!


本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程