Azure中的SQL server:内部连接等效于此处的左连接?

Azure中的SQL server:内部连接等效于此处的左连接?,sql,sql-server,Sql,Sql Server,SQL Server版本:Microsoft SQL Azure(RTM)-12.0.2000.8 2020年10月1日18:48:35版权所有(C)2019 Microsoft Corporation 在最新版本的SQL server(大约2020年)中,SQL server能够优化内部联接吗,或者在适当的情况下使用左联接是否相关 换句话说:这个查询是… select * from MiddleTable left join LeftTable on MiddleTable.LeftTable

SQL Server版本:Microsoft SQL Azure(RTM)-12.0.2000.8 2020年10月1日18:48:35版权所有(C)2019 Microsoft Corporation

在最新版本的SQL server(大约2020年)中,SQL server能够优化内部联接吗,或者在适当的情况下使用左联接是否相关

换句话说:这个查询是…

select * from MiddleTable
left join LeftTable on MiddleTable.LeftTableId = LeftTable.Id
inner join RightTable on MiddleTable.RightTableId = RightTable.Id
where LeftTable.SomeExtraFilterId = RightTable.SomeExtraFilterId 
and RightTable.AnotherExtraFilterId = 'whatever Id value'
…比这个查询效率要高得多,如我所料?:

select * from LeftTable
innerjoin MiddleTable on MiddleTable.LeftTableId = LeftTable.Id
inner join RightTable on MiddleTable.RightTableId = RightTable.Id
where LeftTable.SomeExtraFilterId = RightTable.SomeExtraFilterId 
and RightTable.AnotherExtraFilterId = 'whatever Id value'
附加问题:我的问题有意义吗?还是我完全误解了联接的工作原理——即,它从来不是性能上的差异(即行组合的数量上的差异),而是语法上的差异(取决于您希望以哪个表开始查询)

=========

编辑: 我使用SET STATISTICS IO ON和SET STATISTICS TIME ON来比较查询的执行情况

  • 两个内部联接的结果:

    (163行受影响) 表“LeftTable”。扫描计数0,逻辑读取326,物理读取0,页服务器读取0,预读0,页服务器预读0,lob逻辑读取0,lob物理读取0,lob页服务器读取0,lob页服务器读取0,lob页服务器预读0,lob页服务器预读0

    表“中间表”。扫描计数1,逻辑读取13,物理读取0,页服务器读取0,预读0,页服务器预读0,lob逻辑读取0,lob物理读取0,lob页服务器读取0,lob页服务器读取0,lob页服务器预读0,lob页服务器预读0

    表“RightTable”。扫描计数1,逻辑读取2,物理读取0,页服务器读取0,预读0,页服务器预读0,lob逻辑读取0,lob物理读取0,lob页服务器读取0,lob页服务器读取0,lob页服务器预读0,lob页服务器预读0

    SQL Server执行时间: CPU时间=0毫秒,运行时间=1毫秒。 总执行时间:00:00:00.040

  • 左联接+内联接的结果:

(同上,但RightTable上的逻辑读取数只有一半,但执行时间增加了一倍)


我不知道这其中有多少是通过误差幅度来调用的(这太快了,无法确定),但我接受这两个查询并不像我想的那样有很大的不同。您应该检查执行计划。一般来说,这两个查询是等价的,因为第二个
on
子句将外部联接转换为
内部联接。通常,执行过滤的是
where
子句

select * from MiddleTable
left join LeftTable on MiddleTable.LeftTableId = LeftTable.Id
inner join RightTable on MiddleTable.RightTableId = RightTable.Id
where LeftTable.SomeExtraFilterId = RightTable.SomeExtraFilterId 
and RightTable.AnotherExtraFilterId = 'whatever Id value'
在许多情况下,外部连接和内部连接版本将产生非常相似的执行计划,因此性能将非常相似

通常,外部联接比内部联接对优化器施加更多的约束,因此内部联接通常比外部联接有更多的优化机会。(在某些边缘情况下,内部联接执行计划次优,而外部联接修复了该问题。)

在这种情况下,检测外部联接被过滤为内部联接的情况相当简单,但在其他情况下更复杂。我不知道在寻找这种模式方面有多广泛的数据库。一般来说,数据库开发人员不会专注于优化写得不好的查询


但是,总的来说,您应该编写您想要的查询。在这种情况下,所需的查询似乎是一个内部联接,因此您应该使用它。

完美答案。我使用了设置统计IO和设置统计时间,并更新了问题