sqlserver select的执行顺序

SQL查询执行流程解析
本文详细解释了SQL查询语句的执行顺序,并通过一个具体示例来帮助理解如何优化SQL语句,提高查询效率。

转自网址:http://dev.firnow.com/course/7_databases/sql/sqlServer/20100913/541756.htmls

今天在写一条语句的时候,在查询分析器里边执行
要用10s,换用另外一种写法只用少于1s的时间,同事说是因为Sql句语执行顺序的原因。之前看过一点相
关的书,有一点印象,到网上找了资料,学习下。
逻辑查询处理步骤

复制代码 代码如下:

(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:对FROM子句中的前两个表执行笛卡尔积,生成虚拟表VT1。
2. ON:对VT1应用ON筛选器。只有那些使<join_condition>为真的行才被插入VT2。
3. OUTER(JOIN):如果指定了OUTER JOIN,保留表中未找到匹配的行将作为外部行添加到VT2,生成VT3。
如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到
处理完所有的表为止。
4. 对VT3应用WHERE筛选器。只有使<where_condition>为TRUE的行才被插入VT4。
5. GROUP BY:按GROUP BY 子句中的列列表对VT4中的行分组,生成VT5。
6. CUBE|ROLLUP:把超组插入VT5,生成VT6。
7. HAVING:对VT6应用HAVING筛选器。只有使<having_condition>为TRUE的组才会被插入VT7。
8. SELECT:处理SELECT列表,产生VT8。
9. DISTINCT:将重复的行从VT8中移除,产生VT9。
10. ORDER BY:将VT9中的行按ORDER BY子句中的列列表排序,生成一个有表(VC10)。
11. TOP:从VC10的开始处选择指定数量或比例的行,生成表VT11,并返回给调用者。
以下是其它网友的补充:
好像自已在书写 SQL 语句时由于不清楚各个关键字的执行顺序, 往往组织的 SQL 语句缺少很好的逻辑, 凭感觉 "拼凑" ( 不好意思, 如果您的 SQL 语句也经常 "拼凑", 那您是不是得好好反省一下呢?, 呵呵).
这样做确实是爽了自己, 可苦了机器, 服务器还需要在我们的杂乱无章的 SQL 语句中寻找它下一句需要执行的关键字在哪里.
效率嘛, 由于我们的感觉神经对秒以下的变化实在不敏感, 暂且就认为自已写的 SQL 顺序无关紧要, "反正没什么变化!", 呵呵.其实服务器对每句 SQL 解析时间都会有详细记录的, 大家可以看一下自已按习惯写的 SQL 和按标准顺序写的SQL解析时间差别有多大.
因此, 建议大家在平时工作中 SQL 语句按标准顺序写, 一是专业, 二是实用, 呵呵, 不过我觉得最主要的是心里感觉舒服.
标准的 SQL 的解析顺序为:
(1).FROM 子句, 组装来自不同数据源的数据
(2).WHERE 子句, 基于指定的条件对记录进行筛选
(3).GROUP BY 子句, 将数据划分为多个分组
(4).使用聚合函数进行计算
(5).使用 HAVING 子句筛选分组
(6).计算所有的表达式
(7).使用 ORDER BY 对结果集进行排序
举例说明: 在学生成绩表中 (暂记为 tb_Grade), 把 "考生姓名"内容不为空的记录按照 "考生姓名" 分组, 并且筛选分组结果, 选出 "总成绩" 大于 600 分的.
标准顺序的 SQL 语句为:
select 考生姓名, max(总成绩) as max总成绩
from tb_Grade
where 考生姓名 is not null
group by 考生姓名
having max(总成绩) > 600
order by max总成绩
在上面的示例中 SQL 语句的执行顺序如下:
(1). 首先执行 FROM 子句, 从 tb_Grade 表组装数据源的数据
(2). 执行 WHERE 子句, 筛选 tb_Grade 表中所有数据不为 NULL 的数据
(3). 执行 GROUP BY 子句, 把 tb_Grade 表按 "学生姓名" 列进行分组
(4). 计算 max() 聚集函数, 按 "总成绩" 求出总成绩中最大的一些数值
(5). 执行 HAVING 子句, 筛选课程的总成绩大于 600 分的.
(7). 执行 ORDER BY 子句, 把最后的结果按 "Max 成绩" 进行排序.
好了,看了这些之后,我相信大家都知道了SQL中select语句的执行顺序了吧!哈哈!

### SQL Server 查询执行顺序解析 SQL Server 中的查询执行顺序是指在处理 SQL 查询时,各个子句的实际执行次序。尽管查询是以书写顺序呈现给用户的,但实际上其内部逻辑处理遵循特定的顺序。以下是 SQL Server 查询的主要执行阶段及其顺序: #### 1. FROM 和 JOIN `FROM` 子句用于指定查询的数据源表或视图。在此阶段,SQL Server 将确定参与查询的基础数据集,并应用任何 `JOIN` 条件以组合多个表的内容[^2]。 #### 2. WHERE `WHERE` 子句用于筛选满足条件的记录。此阶段会基于前面构建的虚拟表进一步缩小范围,仅保留符合条件的行[^3]。 #### 3. GROUP BY 如果存在聚合函数(如 `SUM()`、`COUNT()`),则需要先对数据进行分组。`GROUP BY` 子句定义了如何将数据划分为不同的组以便后续计算[^1]。 #### 4. HAVING 类似于 `WHERE`,但作用于分组后的结果集合。它允许我们过滤掉不符合某些条件的分组。 #### 5. SELECT 此时才真正选取所需的列。值得注意的是,在这个阶段还可以引入派生列或者调用内置函数等操作。 #### 6. DISTINCT 如果有重复项,则会在这一环节去除冗余条目。 #### 7. ORDER BY 最后一步是对最终的结果集按照指定字段排序。需要注意的是,这里并不创建新的物理表而是生成一个有序游标[^4]。 #### 性能优化建议 为了提升查询效率,应考虑以下几个方面: - **避免不必要的全表扫描**:尽量不用 `!=` 或 `< >` 这样的比较运算符。 - **合理利用索引**:针对频繁访问的关键字段建立适当类型的索引结构。 - **精确请求所需信息**:不要滥用通配符 `*` ,明确指出感兴趣的属性名即可。 - **采用参数化方式提交动态SQL语句** :这样有助于缓存机制发挥作用进而加快响应速度。 ```sql -- 示例代码展示了一个典型的SQL Server查询过程 SELECT CustomerName, SUM(OrderAmount) AS TotalOrders FROM Customers c INNER JOIN Orders o ON c.CustomerID = o.CustomerID WHERE OrderDate >= '2023-01-01' GROUP BY CustomerName HAVING SUM(OrderAmount) > 1000 ORDER BY TotalOrders DESC; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值