0

因此,SQL Server 不会像通用编程语言中的 if 语句那样以显式方式进行短路。

因此,请考虑以下模拟查询:

SELECT * FROM someTable
WHERE name = 'someValue' OR name in (*some extremely expensive nested sub-query only needed to cover 0.01% of cases*)

假设表中只有 3 行并且它们都匹配 name = 'someValue'。昂贵的子查询会运行吗?假设有 300 万行,除了 1 之外的所有行都可以使用 name = 'someValue' 获取,但需要使用子查询获取的 1 行除外。不需要时是否会评估子查询?

如果有人有类似的真实案例,那么只要在没有 99.99% 案例的子查询的情况下快速获取结果,就可以让 0.01% 的人在获得结果之前等待昂贵的子查询运行。(我知道我上面的具体示例可以使用 SP 中的 IF 语句显式处理,正如此相关线程中所建议的: Sql short circuit OR or conditional exists in where 子句 ,但我们假设这不是一个选项。)

4

1 回答 1

1

正如评论所指出的,SQL Server 中的优化器非常聪明。

您可以使用case. 正如文档所述:

CASE表达式按顺序计算其条件并在满足条件的第一个条件处停止。

请注意,有一些涉及聚合的例外情况。所以,你可以这样做:

SELECT t.*
FROM someTable t
WHERE 'true' = (CASE WHEN t.name = 'someValue' THEN 'true'
                     WHEN t.name in (*some extremely expensive nested sub-query only needed to cover 0.01% of cases*)
                     THEN 'true'
                END)

这种类型的强制排序通常被认为是一个坏主意。一个例外是其中一条路径可能涉及错误,例如类型转换错误) - 但是,现在通常通过try_函数修复。

在您的情况下,我怀疑用适当的索引替换INEXISTS使用适当的索引可能会消除子查询的几乎所有性能损失。然而,那是另一回事。

于 2020-04-23T11:31:16.247 回答