在他的SQL Server 2005书籍和SQL Server 2008书籍中对Itzik Ben-Gan的逻辑查询处理顺序感到困惑

Jus*_*ner 9 sql t-sql sql-server-2005 sql-server-2008

Inside Microsoft SQL Server™2005 T-SQL查询一书中,作者Itzik Ben-Gan告诉我们订单或SQL Server 2005的逻辑查询处理是:

(8)  SELECT (9) DISTINCT (11) <TOP_specification> <select_list>
(1)  FROM <left_table>
(3)       <join_type> JOIN <right_table>
(2)       ON <join_condition>
(4)  WHERE <where_condition>
(5)  GROUP BY <group_by_list>
(6)  WITH {CUBE | ROLLUP}
(7)  HAVING <having_condition>
(10) ORDER BY <order_by_list>

1.  FROM
2.  ON
3.  OUTER (join)
4.  WHERE
5.  GROUP BY
6.  CUBE | ROLLUP
7.  HAVING
8.  SELECT
9.  DISTINCT
10. ORDER BY  <---------------------- NOTE
11. TOP       <---------------------- NOTE
Run Code Online (Sandbox Code Playgroud)

在他的"Microsoft SQL Server 2008内部:T-SQL查询"一书中,他告诉我们以下逻辑查询处理顺序:

(1) FROM
(1-J1) Cartesian Product
(1-J2) ON Filter
(1-J3) Add Outer Rows
(2) WHERE
(3) GROUP BY
(4) HAVING
(5) SELECT
(5-1) Evaluate Expressions
(5-2) DISTINCT
(5-3) TOP       <---------------------- NOTE
(6) ORDER BY    <---------------------- NOTE
Run Code Online (Sandbox Code Playgroud)

请注意这些书的上部摘录中TOPORDER BY的顺序.他们就在对面.我认为这两个步骤非常重要,并且会以不同的顺序给出完全不同的结果.我想知道SQL Server 2008是否从SQL Server 2005中改变了它的存储引擎中的某些东西或其他原因导致这种情况?

谢谢.

小智 6

联机丛书条目中还记录了逻辑处理顺序.小心区分逻辑处理顺序和物理处理顺序.正如BOL条目所述:

以下步骤显示SELECT语句的逻辑处理顺序或绑定顺序.此顺序确定在一个步骤中定义的对象何时可用于后续步骤中的子句.例如,如果查询处理器可以绑定(访问)FROM子句中定义的表或视图,则这些对象及其列可供所有后续步骤使用.相反,因为SELECT子句是步骤8,所以前面的子句不能引用该子句中定义的任何列别名或派生列.但是,它们可以由后续子句引用,例如ORDER BY子句.请注意,语句的实际物理执行由查询处理器确定,并且顺序可能与此列表不同.

查询优化器可以自由地将查询指定的逻辑要求转换为产生正确结果的任何物理执行计划.通常,对于给定的逻辑查询存在许多物理替代方案,因此物理计划通常与上述逻辑处理顺序(用于绑定目的)基本不同.


Wil*_*l A 5

看看这个 - 这是对这个问题的揭露 - 并且提到了Itzik的书.上面的第二个顺序是正确的.

  • 请注意,TOP使用ORDER BY来确定要保留的行.这是逻辑处理模型 - 因此,基于ORDER BY _logically_获取TOP n记录不会导致具有特定排序的行集 - ORDER BY逻辑步骤对结果进行排序.在物理处理方面,ORDER BY将在TOP n之前执行. (2认同)