当连接返回false的变量时,SQL Server是否会查看表?

5
如果我像这样将表A连接到表B...
select A.* from A 
left outer join B on A.Id = B.aId and @param = 'someValue'

如果 @param 不等于 'someValue',SQL Server 是否会尝试从表 B 匹配记录,还是聪明地知道条件永远不会成立?


你为什么会这样做?还是只是假想的情况? - Mark Canlas
我试图找到一种有效的方法来编写查询,其条件可能存在于15个不同的表中之一,具体取决于指示哪个表的参数。 - adam0101
听起来这是你的根本问题,这只是其症状。什么样的查询涉及到15个不同的实体? - Mark Canlas
2个回答

7

因此,虽然在特定情况下,当@param具有不同的值时,外部连接表可能永远不会被探测,但您不应该依赖它来确保正确性。请注意,探测意味着在表中搜索实际值。元数据信息将始终被检查。例如,您不能欺骗并要求加入不存在的表。

特别地,不要尝试创建一个单一的查询,而应该有两个不同的查询(一个连接,一个不连接)。


1

最好将这段代码放在一个新的回答中,而不是评论中,但这展示了Remus所说的一些内容:

CREATE PROCEDURE dbo.Test_Params
    @param1 INT
WITH RECOMPILE
AS
BEGIN
    SELECT
        o.object_id,
        c.object_id
    FROM
        sys.objects o
    LEFT OUTER JOIN sys.columns c ON
        c.object_id = o.object_id AND
        @param1 = 1
    OPTION
        (RECOMPILE)
END
GO


EXEC dbo.Test_Params 1
EXEC dbo.Test_Params 2

如果您在这两个EXEC语句上执行一个执行计划,您会发现sys.columns出现在两个执行计划中,但在第二个执行计划中,在连接发生之前所有行都被过滤。请注意,它们并没有完全被查询短路。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接