T-SQL查询语句的执行步骤

T-SQL是需要优化的。而优化的前提是你对它的执行步骤有清楚的认识。我经常去给讲课或者咨询辅导的时候,就发现很多朋友对此了解甚少。下面截取了我的一个PPT,给大家参考一下

image

下面这个脚本可以解释这个过程

/*
这个脚本用来帮助用户理解T-SQL查询的逻辑顺序和原理。
作者:陈希章
*/

/*
准备数据架构和数据
*/
SET NOCOUNT ON;
USE tempdb;
GO
IF OBJECT_ID('dbo.Orders') IS NOT NULL
  DROP TABLE dbo.Orders;
GO
IF OBJECT_ID('dbo.Customers') IS NOT NULL
  DROP TABLE dbo.Customers;
GO
CREATE TABLE dbo.Customers
(
  customerid  CHAR(5)     NOT NULL PRIMARY KEY,
  city        VARCHAR(10) NOT NULL
);

INSERT INTO dbo.Customers(customerid, city) VALUES('FISSA', 'Madrid');
INSERT INTO dbo.Customers(customerid, city) VALUES('FRNDO', 'Madrid');
INSERT INTO dbo.Customers(customerid, city) VALUES('KRLOS', 'Madrid');
INSERT INTO dbo.Customers(customerid, city) VALUES('MRPHS', 'Zion');

CREATE TABLE dbo.Orders
(
  orderid    INT        NOT NULL PRIMARY KEY,
  customerid CHAR(5)    NULL     REFERENCES Customers(customerid)
);

INSERT INTO dbo.Orders(orderid, customerid) VALUES(1, 'FRNDO');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(2, 'FRNDO');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(3, 'KRLOS');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(4, 'KRLOS');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(5, 'KRLOS');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(6, 'MRPHS');
INSERT INTO dbo.Orders(orderid, customerid) VALUES(7, NULL);

/*
一个测试查询,检索那些订单个数小于3的客户,并且按订单总数排序(升序)
*/
SELECT C.customerid, COUNT(O.orderid) AS numorders
FROM dbo.Customers AS C
  LEFT OUTER JOIN dbo.Orders AS O
    ON C.customerid = O.customerid
WHERE C.city = 'Madrid'
GROUP BY C.customerid
HAVING COUNT(O.orderid) < 3
ORDER BY numorders;

/*第一步:处理FROM子句,把来源的表进行CROSS JOIN(笛卡尔乘积)
我这里把结果做一个生成表查询,写到一个临时表(VT1)中去
*/
SELECT C.customerid as Customer,c.city,o.*  INTO #VT1 FROM dbo.Customers C,dbo.Orders  O
SELECT * FROM #VT1
--返回28行数据(4*7)

--第二步:处理ON子句,只把那些两个表的customerid匹配的行找出来,我把它们放到VT2中去
SELECT temp.* INTO #VT2 FROM (SELECT * FROM #VT1 WHERE Customer=customerid) temp
SELECT * FROM #VT2
--返回6行数据

--第三步:根据JOIN语句的类型,决定是否要添加行到VT2中去,例如如果是LEFT  JOIN的话,那么就要检查坐边的表(我们这里是customers表)的连接键值是否都存在,如果不存在就要去添加到VT2中
SELECT temp.* INTO #VT3 FROM
(SELECT * FROM #VT2
UNION ALL
SELECT CustomerID,City,NULL,NULL FROM dbo.Customers c WHERE NOT EXISTS(SELECT DISTINCT Customer FROM #VT2 WHERE Customer=c.CustomerID)) temp
SELECT * FROM #VT3
--返回7行数据,其中有一个客户,因为没有订单,这一步中被添加进来。它的Orders的记录被标记为NULL

--第四步:处理WHERE 子句,对VT3的结果集进行过滤,我们的条件是city=Madid
SELECT temp.* INTO #VT4 FROM
(SELECT * FROM #VT3 WHERE city='Madrid') temp
SELECT * FROM #VT4
--返回6行数据,因为有一个客户不是这个城市的

--第五步:处理GROUP子句,进行分类汇总
SELECT temp.* INTO #VT5 FROM
(SELECT Customer,COUNT(OrderID)  as orderidcount,COUNT(city) as citycount,Count(customerid)  as customeridcount FROM #VT4 GROUP BY Customer) temp
SELECT * FROM #VT5
--返回3行数据,根据客户分组,统计了订单的个数
--这里会不会去统计其他列的汇总呢

--因为没有WITH Rollup和WITH Cube语句,所以跳过第六步,进入HAVING子句的处理

--第六步:处理HAVING子句,对GROUP之后的结果进行筛选,我们这里的条件是orderidcount<3
SELECT temp.* INTO #VT6 FROM
(SELECT * FROM #VT5 WHERE orderidcount<3) temp
SELECT * FROM #VT6
--返回2行数据

--第七步:使用SELECT 的字段列表过滤结果集
SELECT #VT6.Customer,#VT6.orderidcount as  numorders  INTO #VT7 FROM #VT6
SELECT * FROM #VT7
--还是2行数据,只不过只有两个列了

--第八步:跳过DISTINCT,进行OrderBy操作
SELECT #VT7.* INTO #VT8 FROM #VT7 Order By #VT7.Customer
SELECT * FROM #VT8
--返回2行数据,经过排序

--这个查询结束演示。完整的8个步骤

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对你的问题,我来简单介绍一下从T-SQL查询语句角度出发,如何实现查询优化。 首先,我们需要了解T-SQL查询的执行过程,它通常包括以下几个步骤: 1. 解析查询语句,生成查询执行计划。 2. 执行查询计划,获取数据。 3. 对数据进行排序、分组、筛选等操作。 4. 返回查询结果。 在这个过程中,查询优化就是在保证查询语义不变的前提下,尽可能地减少查询的执行时间、资源消耗等方面的优化。 以下是一些常见的查询优化技巧: 1. 索引优化:为查询涉及到的表添加合适的索引,可以大大提高查询速度。索引的选择需要根据查询条件、表大小、数据分布等因素进行综合考虑。 2. 查询重构:通过优化查询语句的结构,可以减少不必要的计算和读写操作。比如,尽量少使用子查询、避免使用“*”通配符、使用JOIN代替WHERE子句等。 3. 统计信息优化:数据库中存储的统计信息可以帮助查询优化器更好地选择查询计划。我们可以通过更新统计信息、增加采样率等方式来提高查询性能。 4. 查询缓存:数据库会缓存查询结果,如果查询相同的语句,可以直接返回缓存中的结果,避免重新执行查询,从而提高查询速度。 总的来说,查询优化是一个综合性的工作,需要根据具体的业务场景和数据特征进行针对性的优化。在实际应用中,我们需要不断地监测查询性能、分析瓶颈,针对性地进行优化,以提高应用的性能和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值