条件中的逻辑运算符 OR AND 和 WHERE 中的条件顺序

gar*_*rik 38 sql-server-2008 sql-server optimization t-sql condition

让我们检查这两个语句:

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

IF (CONDITION 3) AND (CONDITION 4)
...
Run Code Online (Sandbox Code Playgroud)

如果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
Run Code Online (Sandbox Code Playgroud)

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

结论:

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

为了真正回答这个问题,让我们来看看两者如何处理条件。C++/C#/VB 都在语言规范中定义了短路以加速代码执行。为什么要在第一个已经为真的情况下评估 N OR 条件,或者在第一个已经为假的情况下评估 M AND 条件。

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

作为开发人员,您必须意识到 SQL Server 不会像在其他编程语言中那样进行短路,并且您无法强迫它这样做。

Mic*_*Sim 29

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

SQL Server 如何短路 WHERE 条件评估

它会在感觉时发生,但不是您立即想到的方式。

作为开发人员,您必须意识到SQL Server 不会像在其他编程语言中那样进行短路,并且您无法强制它使用.

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

SQL Server 是否短路?

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

  • 显然有一些边缘情况(或错误),甚至“case”[不安全](http://bartduncansql.wordpress.com/2011/03/03/dont-depend-on-expression-short-circuiting- in-t-sql-not-even-with-case/) (2认同)

Jac*_*las 8

在 T-SQL 中,IF语句可以短路,但不能依赖它按顺序计算表达式