【问题标题】:In which order does SQL Server apply filters - top down or bottom up (first to last or last to first)?SQL Server 应用过滤器的顺序是自上而下还是自下而上(从上到下或从上到下)?
【发布时间】:2020-03-08 17:39:01
【问题描述】:

当我编写代码时,我喜欢确保我正在优化性能。我假设这包括对过滤器进行排序,使重型减速器(过滤掉很多行)在顶部,而较轻的减速器(过滤掉几行)在底部。

但是当我的过滤器出现错误时,我注意到 SQL Server 首先捕获底部过滤器中的错误,然后捕获顶部过滤器中的错误。这是否意味着 SQL Server 自下而上处理过滤器?

例如(为了清楚起见,我是过滤器 - 故意输入错误 - 在 WHERE 子句而不是 JOIN 子句中):

select
   l.Loan_Number
   ,l.Owner_First_Name
   ,l.Owner_Last_Name
   ,l.Street
   ,l.City
   ,l.State
   ,p.Balance
   ,p.Delinquency_Bucket
   ,p.Next_Due_Date
from
   Location l
   join Payments p on l.Account_Number = p.Account_Number
where
   l.OOOOOwner_Last_Name = 'Kostoryz' -- I assume this would reduce the most, so I put it first
   and p.DDDDelinquency = '90+' -- I assume this would reduce second most, so I put it second
   and l.SSSState <> 'WY' -- I assume this would reduce the least, so I put it last

然而,SQL Server 将返回的第一个错误将是 ERROR - THERE IS NO COLUMN SSSState IN Location TABLE

它将返回的下一个错误将是错误 - 付款表中没有列 DDDDelinquency

这是否意味着 State 过滤器将在 Delinquency 过滤器之前应用,而 Delinquency 过滤器将在 Last_Name 过滤器之前应用?

【问题讨论】:

  • 查询将被编译,引擎将确定执行 where 子句条件的顺序以及要使用的索引。顺序无关紧要
  • 过滤器按照查询引擎认为将提供最快结果的顺序应用。使用 CTRL-L 查看估计的查询计划,该计划将在应用过滤器时向您显示。请注意,查询计划可以从执行更改为执行。您编写它们的实际顺序几乎没有区别。

标签: sql sql-server tsql filter


【解决方案1】:

大约会发生三个阶段,即 DBMS 以文本形式接收查询,直到您获得结果。

  1. 文本通常被转换成某种内部格式,DBMS 可以更轻松地使用。

  2. 从 DBMS 尝试计算实际执行的最佳方式的内部格式来看,您可以将其视为在那里开发的一个小程序。

  3. 该程序实际执行,结果写入某个位置(在内存中),您可以从中获取它。

(这些阶段可能可以划分为更小的子阶段,但我猜这里不需要那种详细程度。)

现在考虑到这一点,请注意,您提到的错误之一是在第 1 阶段发出的,当 DBMS 尝试绑定数据库中的实际对象但找不到它们时。此时查询远未执行,绑定完成的顺序与稍后实际应用过滤器的顺序无关。此外,之后是第 2 阶段。为了找到最佳的执行方式,DBMS 可以并将重新排序(不一定只有过滤器)。因此,您如何订购过滤器或绑定顺序如何通常并不重要。 DBMS 将查看它们并决定哪个更早应用,哪个可以等到以后应用。

请记住,SQL 是一种描述性语言。我们不是告诉机器该做什么——我们在用命令式语言编写程序时通常会做什么——而是描述我们想要的结果,让机器弄清楚如何计算它以及如何以最好的方式做到这一点或者至少是一个好方法。

(当然,这种优化可能并不总是 100% 有效。有时查询中有一些技巧可以帮助 DBMS 找到更好的解决方案。但是对于您发布的那种查询,任何 DBMS 都应该可以很好地应对无论您如何订购过滤器,都能很好地找到应用过滤器的好顺序。)

【讨论】:

    【解决方案2】:

    在 SQL Server 尝试运行查询之前,它会创建一个查询执行计划 (QEP)。您看到的错误是在构建 QEP 时发生的。您无法根据收到这些错误的顺序推断有关“过滤器”序列的任何信息。 一旦你提供了一个有效的查询,SQL Server 将构建一个 QEP 并管理它用来满足查询的操作。 QEP 将基于许多因素,包括表上可用的索引和统计信息 - 尽管通常不是您在 WHERE 子句中指定条件的顺序。有办法做到这一点,但通常不建议这样做。

    【讨论】:

      【解决方案3】:

      简而言之,不。过滤器的顺序无关紧要。

      在高层次上,查询在执行之前会经过多个阶段。阶段是:

      • 解析和规范化(检查语法并验证表格)

      • 编译和优化(编译和优化代码以供执行)

      在优化阶段,检查表统计信息、索引统计信息以得出执行查询的最佳执行计划。因此,文件管理器会根据统计信息进行检查,并根据统计信息按顺序应用。因此,查询中过滤器的顺序并不重要。列统计信息 DO MATTER。

      Read more on Stages of query execution

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-14
        • 2012-10-26
        • 1970-01-01
        • 2014-03-14
        • 2021-10-16
        • 2021-05-08
        • 1970-01-01
        相关资源
        最近更新 更多