29

在 Sql Server 2005 中,当我有多个参数时,我能保证评估顺序总是从左到右吗?

使用示例:

select a from table where c=1 and d=2

在此查询中,如果“c=1”条件失败,则永远不会评估“d=2”条件?

PS-“c”是一个整数索引列,d 是一个大型 varchar 且不可索引的列,需要全表扫描

更新我试图避免执行两个查询或条件语句,我只需要类似的东西:如果“c 条件”失败,有一种方法可以避免执行繁重的“d 条件”,因为在我的情况下不需要它。

4

7 回答 7

32

无法保证评估顺序。优化器将尝试使用可用信息找到执行查询的最有效方式。

在您的情况下,由于 c 已编入索引而 d 未编入索引,因此优化器应查看索引以查找与 c 上的谓词匹配的所有行,然后从表数据中检索这些行以评估 d 上的谓词。

但是,如果它确定 c 上的索引不是很有选择性(尽管在您的示例中不是,gender 列很少被有用索引),它可能决定无论如何都要进行表扫描。

要确定执行顺序,您应该获得查询的解释计划。但是,请意识到该计划可能会根据优化器认为的最佳查询而改变。

于 2009-01-27T16:43:50.407 回答
4

SQL Server 将为它执行的每条语句生成一个优化的计划。您无需订购 where 子句即可获得该好处。您唯一的保证是它将按顺序运行语句:

SELECT A FROM B WHERE C
SELECT D FROM E WHERE F

将在第二行之前运行第一行。

于 2009-01-27T16:41:42.983 回答
3

控制评估顺序的一种方法是使用 CASE 表达式。

[编辑]

我试图表达的流行观点是:

您不能依赖表达式评估顺序来处理诸如“WHERE OR”之类的事情,因为优化器可能会选择一个在第一个谓词之前评估第二个谓词的计划。但是 CASE 语句中表达式的求值顺序是固定的,因此您可以依赖 CASE 语句的确定性短路求值。

它确实比下面网站中解释的要复杂一些:

http://blogs.msdn.com/b/bartd/archive/2011/03/03/don-t-depend-on-expression-short-circuiting-in-t-sql-not-even-with-case。 aspx

于 2009-01-27T16:51:57.473 回答
2

您可以查看查询的执行计划并确定它实际尝试执行的操作。我认为 SQL Server 的查询引擎应该进行这种类型的扫描,并将其智能地转换为操作。就像,如果你做“昂贵的操作和假”,它会很快评估为假。

根据我了解到的情况,您输入的内容(并且可能)与实际执行的内容不同。你只是告诉服务器你期望什么类型的结果。它如何获得答案与您提供的代码的从左到右无关。

于 2009-01-27T16:43:23.200 回答
2

如果您想确保可以检查Query Execution Plan。MSSQL 构建/优化的执行计划足够聪明,可以在 varchar 列之前检查索引列。

于 2009-01-27T16:52:16.520 回答
2

当我们引用的条件仅包含文字或常量时,就会完成短路。因此,例如,假设我们有一个表 TableA,其中 num 列包含从 1 到 10 的所有正数,然后如果我编写此查询。

从 TableA 中选择 num,其中 TableA.num < 0 AND 1/0 = 10。

这将导致错误。

编译器是否足够聪明,可以确定我的第二个子句由常量组成,因此它应该在评估需要从表或索引进行任何扫描的子句之前评估它?

于 2009-11-04T06:46:38.803 回答
1

MS SQL Server 查询优化器确实短路了,是的。保证。

运行这个:

select 1 where 1 = 0 and 1 / 0 = 10

即使你被零除,它也会运行得很好并且不会出错,因为查询优化器会短路评估 where 子句。这对您使用“and”并且其中一个和部分是常量的任何 where 子句都有影响。

于 2009-01-27T16:53:11.043 回答