逻辑运算符OR AND,条件和条件在WHERE中


33

让我们检查以下两个语句:

IF (CONDITION 1) OR (CONDITION 2)
...

IF (CONDITION 3) AND (CONDITION 4)
...

如果CONDITION 1TRUE,将CONDITION 2被检查吗?
如果CONDITION 3FALSE,将CONDITION 4被检查吗?

关于以下条件WHERE:SQL Server引擎会优化WHERE子句中的所有条件吗?程序员是否应该以正确的顺序放置条件,以确保SQL Server优化程序以正确的方式解决该问题?

添加:

感谢Jack的链接,这让T-SQL代码感到惊讶:

IF  1/0 = 1 OR 1 = 1
      SELECT 'True' AS result
ELSE
      SELECT 'False' AS result


IF  1/0 = 1 AND 1 = 0
      SELECT 'True' AS result
ELSE
      SELECT 'False' AS result

在这种情况下,不会引发除以零的异常。

结论:

如果C ++ / C#/ VB发生短路,SQL Server为什么不能短路?

为了真正回答这个问题,让我们看一下两者在条件下如何工作。C ++ / C#/ VB均具有语言规范中定义的短路功能,以加快代码执行速度。为什么要在第一个条件为真时评估N OR条件,或者在第一个条件为false时评估M AND条件呢?

作为开发人员,我们必须意识到SQL Server的工作原理有所不同。这是一个基于成本的系统。为了获得我们查询的最佳执行计划,查询处理器必须评估每个条件,并为其分配成本。然后,对这些成本进行整体评估,以形成一个阈值,该阈值必须低于SQL Server为良好计划所定义的阈值。如果成本低于定义的阈值,则使用计划,如果不是,则使用条件成本的不同组合再次重复整个过程。这里的成本要么是扫描,要么是搜索,要么是合并联接,要么是哈希联接等。因此,根本无法实现C ++ / C#/ VB中的短路。您可能会认为强制在列上使用索引被视为短路,但事实并非如此。它仅强制使用该索引,从而缩短了可能的执行计划的列表。该系统仍基于成本。

作为开发人员,您必须意识到SQL Server不会像其他编程语言那样发生短路,并且您无能为力。


最终报价块从哪里来?您可以添加参考吗?
Nick Chammas 2012年

Answers:


25

在SQL Server中,不能保证是否在WHERE子句中按顺序处理语句。允许语句短路的单个表达式是CASE- WHEN。以下是我在Stackoverflow上发布的答案:

SQL Server如何短路WHERE条件评估

它会在感觉到时就出现,但不会以您立即想到的方式出现。

作为开发人员,您必须意识到SQL Server不会像其他编程语言那样发生短路,并且您无能为力

有关更多详细信息,请检查上述博客条目中的第一个链接,该链接指向另一个博客:

SQL Server是否短路?

最终裁决?好吧,我还没有真正的人,但是可以肯定地说,唯一可以确保特定短路的时间是在CASE表达式中表达多个WHEN条件时。 使用标准的布尔表达式,优化器将根据您要查询的表,索引和数据在合适的地方移动内容。


2
显然,有些极端情况(或错误)甚至case 都不安全
Jack Douglas

1
我还将演示CASE中断的另一种情况(ha!):dba.stackexchange.com/questions/12941/…–
Aaron Bertrand


0

SQL是一种声明性编程语言。不同于命令式编程语言C ++ 。

也就是说,您可以告诉它最终结果是什么,但是您无法决定结果如何执行,这完全取决于引擎。

保证内部“短路”(或任何其他控制流)的唯一真实方法WHERE是使用索引视图,临时表和类似机制。

PS。您还可以使用执行计划提示(以“提示”引擎如何执行查询,要使用的索引以及如何使用它们),只是以为我应该提到它,而我们正在讨论这个主题。


-4

1)-或(任何一个或两个条件为TRUE)

如果条件1为TRUE,则条件2也将检查为TRUE或FALSE

--AND(两个条件都必须为TRUE)

如果条件1为FALSE,则将不检查条件2


“如果条件1为FALSE,则将不检查条件2”这是不正确的。请参阅上面的答案。SQL Server可能仍会评估条件2,因为它没有在WHERE子句中执行短路评估。
Nick Chammas

-4

控制WHERE子句中条件的唯一方式是使用方括号将它们分组在一起。

WHERE Col1 = 'Something' AND Col2 = 'Something' OR Col3 = 'Something' and Col4 = 'Something'

WHERE (Col1 = 'Something' AND Col2 = 'Something') OR (Col3 = 'Something' and Col4 = 'Something')

只是好奇。这两个条件有何不同?不同的结果,性能,执行计划?我以为它们是等效的。
ypercubeᵀᴹ

对于第一个,您需要匹配Col1,Col4和Col2或Col3。在第二行中,要匹配Col1和Col2,或者您需要匹配Col3和Col4,但是Col1和Col4永远都不需要一起求值。
mrdenny 2012年

1
不,你错了。AND的优先级高于OR。两者是等效的。您所说的对WHERE Col1 = x AND (Col2 = x OR Col3 = x) AND Col4 = x查询来说是正确的。请参阅SQL-小提琴测试
ypercubeᵀᴹ
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.