0

我正在尝试像这样实现有条件的加入

declare @JoinWithT2 bit = 1;

select T1.* from T1 
inner join T2 on (@JoinWithT2 = 0 or T1.Id=T2.Id)

这很好用,当我传递@JoinWithT2值 1 时,它使用两个表的连接给我结果,当我传递@JoinWithT2值 0 时,它返回 T1 忽略连接的所有结果。

这一切都很好,但我担心性能,因为上面也可以这样实现

if @JoinWithT2=0
begin
    select T1.* from T1 
end
else
begin
    select T1.* from T1 
    inner join T2 on (T1.Id=T2.Id)
end

实现条件连接的最佳方法是第一个还是第二个?

我个人觉得第二个应该更好的性能,因为它根本不涉及 T2 而第一个查询可能使用 T2

4

3 回答 3

2

我很困惑。以下应该执行笛卡尔积或内连接,具体取决于 的值JoinWithT2

declare @JoinWithT2 bit = 1;

select T1.*
from T1 inner join
     T2
     on (@JoinWithT2 = 0 or T1.Id=T2.Id);

When @JoinWithT2is 0thenon子句始终为真。这join相当于 a cross join

以下是进行连接或获取第一个表的条件逻辑:

declare @JoinWithT2 bit = 1;

select T1.*
from T1 left outer join
     T2
     on (@JoinWithT2 = 1 and T1.Id=T2.Id)
where @JoinWithT2 = 0 or T2.Id is not null;

从性能的角度来看,单独的语句if通常会表现得更好。有更多信息可供 SQL 引擎优化。但是,如果您对 有一个索引T2(id),那么相对于查询的其他部分(例如将结果返回给用户)而言,性能差异可能并不显着。

于 2013-07-25T19:10:39.703 回答
1

在这种情况下,最好的选择可能是使用动态 SQL,尽管在新版本的 SQL Server 中或条件并不像旧版本的 SQL Server 那样糟糕。if 语句很好,但在添加两个或三个其他表后很难维护,这些表可能会或可能不会根据特定条件连接。随着时间的推移和更多的东西被添加到查询中,or 条件可能会变慢。仅使用此特定参数集所需的内容构建搜索类型查询通常是最佳选择。

您可能想阅读:

http://www.sommarskog.se/dyn-search-2008.html

或(如果您使用 SQL SERVER 2005 或更早版本) http://www.sommarskog.se/dyn-search-2005.html

于 2013-07-25T19:15:36.577 回答
1

如果您不从 T2 中选择任何内容,为什么需要加入?同样可以通过以下方式实现:

select T1.*
from T1 
where @JoinWithT2 = 0 or T1.Id in (select T2.Id from T2);
于 2013-07-25T19:19:40.513 回答