我有以下 SQL 查询,
SELECT TOP 5 C.CustomerID,C.CustomerName,C.CustomerSalary
FROM Customer C
WHERE C.CustomerSalary > 10000
ORDER BY C.CustomerSalary DESC
在适当的解释下,以下的执行顺序是什么,
- 顶部条款
- WHERE 子句
- ORDER BY 条款
我有以下 SQL 查询,
SELECT TOP 5 C.CustomerID,C.CustomerName,C.CustomerSalary
FROM Customer C
WHERE C.CustomerSalary > 10000
ORDER BY C.CustomerSalary DESC
在适当的解释下,以下的执行顺序是什么,
查看SELECT 语句的文档,特别是本节:
SELECT语句的逻辑处理顺序
以下步骤显示了 SELECT 语句的逻辑处理顺序或绑定顺序。此顺序确定一个步骤中定义的对象何时可用于后续步骤中的子句。例如,如果查询处理器可以绑定到(访问)在 FROM 子句中定义的表或视图,则这些对象及其列可用于所有后续步骤。相反,因为 SELECT 子句是第 8 步,所以在该子句中定义的任何列别名或派生列都不能被前面的子句引用。但是,它们可以被后续子句引用,例如 ORDER BY 子句。请注意,语句的实际物理执行由查询处理器确定,并且顺序可能与此列表不同。
给出以下顺序:
FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE or WITH ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP
WHERE
ORDER BY
TOP
这是一篇很好的文章:http: //blog.sqlauthority.com/2009/04/06/sql-server-logical-query-processing-phases-order-of-statement-execution/
只需记住这句话:- Fred Jones 的 Weird Grave 有几只沉闷的猫头鹰
取每个单词的第一个字母,你会得到:-
FROM
(ON)
JOIN
WHERE
GROUP BY
(WITH CUBE or WITH ROLLUP)
HAVING
SELECT
DISTINCT
ORDER BY
TOP
希望有帮助。
根据您的情况,这是确切的执行顺序。
1-FROM
2-WHERE
3-SELECT
4-ORDER BY
5-TOP
TOP、WHERE 和 ORDER BY 不是“执行”的——它们只是描述了期望的结果,并且数据库查询优化器(希望)确定了实际执行的最佳计划。“声明所需结果”与物理实现方式之间的分离是使 SQL 成为“声明性”语言的原因。
假设在 上有一个索引CustomerSalary
,并且该表未聚集,您的查询可能会作为索引查找 + 表堆访问执行,如此SQL Fiddle所示(单击底部的查看执行计划):
可以看到,首先通过Index SeekCustomerSalary
找到正确的值,然后通过RID Lookup(Row ID Lookup)从表堆中检索到该值所属的行。Top仅用于此处显示(并且成本为 0%),嵌套循环也是如此 - 在任何情况下,起始索引查找将(最多)返回一行。整个查询相当有效,并且可能只需要很少的 I/O 操作。
如果表是clustered,您可能会有另一个索引查找而不是表堆访问,如此SQL Fiddle所示(注意 DDL SQL 中缺少 NONCLUSTERED 关键字):
但请注意:这次我很幸运得到了“正确”的执行计划。查询优化器可能选择了全表扫描,这有时在小表上实际上更快。在分析查询计划时,请始终尝试对实际数量的数据进行分析!
访问https://msdn.microsoft.com/en-us/library/ms189499.aspx以获得更好的解释。
以下步骤显示了 SELECT 语句的逻辑处理顺序或绑定顺序。此顺序确定一个步骤中定义的对象何时可用于后续步骤中的子句。例如,如果查询处理器可以绑定(访问)在 FROM 子句中定义的表或视图,则这些对象及其列可用于所有后续步骤。相反,因为 SELECT 子句是第 8 步,所以在该子句中定义的任何列别名或派生列都不能被前面的子句引用。但是,它们可以被后续子句引用,例如 ORDER BY 子句。请注意,语句的实际物理执行由查询处理器确定,并且顺序可能与此列表不同。
从
上
加入
在哪里
通过...分组
WITH CUBE 或 WITH ROLLUP
拥有
选择
清楚的
订购方式
最佳
我的 0.02 美元在这里。
这里有两个不同的概念:逻辑执行顺序和查询执行计划。另一个是看是谁回答了以下问题:
第一个问题由逻辑执行顺序来回答。布赖恩的回答显示了它是什么。这是 SQL 理解您的命令的方式:“从客户表(别名为 C)只考虑 C.CustomerSalary > 10000 的行,按 C.CustomerSalary 的降序对它们进行排序,并选择为前 5 行列出的列”。结果集将遵循该含义
第二个问题的答案是查询执行计划——它取决于您的架构(表定义、数据的选择性、客户表中的行数、定义的索引等),因为很大程度上依赖于 SQL Server 优化器的内部工作。