sqlserver中select语句的执行顺序
对于一条select查询语句的执行顺序,很多开发人员并不是十分的了解,对于他们来说,只关心最终得到的结果,并不关心中间的过程。但作为一名合格的DBA,只有理解整个执行过程,才能调教出更加准确、更加高效的sql语句。
举个例子:
SELECT TOP 100 a.customer_id, COUNT(b.order_id) as total_orders
FROM customers AS a
LEFT JOIN orders AS b ON a.customer_id = b.customer_id
WHERE a.city = 'hangzhou'
GROUP BY a.customer_id
HAVING count(b.order_id) < 2
ORDER BY total_orders DESC
针对这条查询语句,查询处理的每一个阶段(关键字前面的序号为SELECT执行顺序)介绍如下:
序号 | 关键字 | 执行过程 |
---|---|---|
1 | FROM | 对FROM子句中的前两个表执行笛卡尔积(cross join),生成虚拟表VT1 |
2 | ON | 对VT1应用ON筛选器,只有满足join条件的行才被插入VT2 |
3 | JOIN | 若FROM子句包含两个以上的表,则对VT2和下一个表重复执行步骤1到3,直到处理完所有的表为止 |
4 | WHERE | 对VT3应用WHERE筛选器,只有满足where条件的行才被插入VT4 |
5 | GROUP BY | 按GROUP BY子句中的列列表对VT4中的行分组,生成VT5 |
6 | WITH CUBE / ROLLUP | 把超组(Suppergroups)插入VT5,生成VT6 |
7 | HAVING | 对VT6应用HAVING筛选器,只有使 |
8 | SELECT | 处理SELECT列表,产生VT8 |
9 | DISTINCT | 将重复的行从VT8中移除,产生VT9 |
10 | ORDER BY | 将VT9中的行按ORDER BY 子句中的列列表排序,生成游标(VC10) |
11 | TOP | 从VC10的开始处选择指定数量或比例的行,生成表VT11,并返回给用户 |
讨论一下
下面的2条select语句,你认为结果是一样的吗?
select ord.* from customers as cus
left join orders as ord on cus.customerid = ord.customerid
and cus.customerid = 'FRNDO'
where ord.city = 'hangzhou'
select ord.* from customers as cus
left join orders as ord on cus.customerid = ord.customerid
where ord.city = 'hangzhou'
and cus.customerid = 'FRNDO'