代码之家  ›  专栏  ›  技术社区  ›  t3mujin

选择“Where子句”评估顺序

  •  25
  • t3mujin  · 技术社区  · 16 年前

    在SQL Server 2005中,当我有多个参数时,是否可以保证评估顺序将 总是 从左到右?

    举个例子:

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

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

    ps-“c”是一个整数索引列,d是一个大的varchar和不可索引列,需要进行完整的表扫描

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

    7 回复  |  直到 10 年前
        1
  •  28
  •   kdgregory    16 年前

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

    在您的示例中,由于C是索引的,而D不是索引的,所以优化器应该查找索引,以查找与C上谓词匹配的所有行,然后从表数据中检索这些行,以计算D上的谓词。

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

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

        2
  •  4
  •   Orion Adrian    16 年前

    SQL Server将为它执行的每个语句生成一个优化的计划。你不必为了得到那个好处而去订你的WHERE条款。唯一值得夸耀的是它将按顺序运行语句,因此:

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

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

        3
  •  2
  •   Mark Canlas    16 年前

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

    根据我学到的,你输入的和实际执行的不同。您只是告诉服务器您期望的结果类型。它是如何得到答案的,与您提供的代码从左到右不相关。

        4
  •  2
  •   cgreeno    16 年前

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

        5
  •  1
  •   Robert C. Barth    16 年前

    MS SQL Server查询优化器短路,是的。放心。

    运行此操作:

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

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

        6
  •  1
  •   Nitin Midha    15 年前

    当我们所引用的条件只包含文本或常量时,就会发生短路。例如,我们有一个表table a,它有列num,所有的正数都在1到10之间,如果我编写这个查询的话。

    从tablea中选择num,其中tablea.num<0和1/0=10。

    这将导致错误。

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

        7
  •  1
  •   Ric Tokyo    10 年前

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

    [编辑]

    我想表达的流行观点是:

    不能依赖表达式计算顺序 _156;where or_156;,因为优化器可能选择计划 计算第一个谓词之前的第二个谓词。但是 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