MS SQL Server 2005 物理查询处理中的各个阶段 (二)

时间:2021-08-22 03:44:58

MS SQL Server 2005 物理查询处理中的各个阶段()

大家好,我是浪客,和大家分享一些最近我从《Microsoft SQL SERVER 2005技术内幕:T-SQL查询》书中的心得,终于出“二“了,回应很多朋友的需求,今天抽空写了物理查询阶段,

上文中你真的了解T-SQL逻辑查询吗?提到的这种搜索方式,也许很多人不明白(包括我,我看之前简直感到诧异),很多都想 如果表的记录有10000000~!#@条,那每次的CROSS JOIN 将会长生 m*n的记录,我们就假设是1W 1w的平方还是有点点恐怖的,所以实际存储引擎并不是如此查询的,但是讲清楚 逻辑查询很重要,因为那是物理查询的基础,我觉得 理解数据库引擎的查询处理方式有助于 开发人员在生产过程中做出正确的选择。PS:(有朋友说文章很多都“借鉴“别人的例子,我想是好东西用什么例子都不重要吧,只要能分享给大家,我抄都抄过来,再说是我对书的一些总结,呵呵~,这里要感谢作者Lubor Kollar,他是书中该章节的作者,是MS SQL SERVER 2005开发人员)。

那么开始吧,当一个查询你到达数据库引擎的时候 SQL SERVER 执行两个主要的步骤来产生结果,一步就是 “查询编译”,一个是“生成查询计划”。首先提一下为什么存储过程的效率总是比应用程序级别的T-SQL语句来的更迅速,首先抛开网络传输T-SQL语句的时间不管,我们利用应用程序发送的T-SQL语句,交个数据库执行,他首先就要对T-SQL语句进行编译,在SQL中编译的概念,和我们写应用程序理解应该是一致的,包括语法的检查,代数化以及查询优化,就像我们的应用程序(我是搞.NET的),编译器对你的C#代码进行编译,先检查语法的错误,然后生成dlldll 中就包括对整个类库的描述类似于SQL中的执行计划,回到SQL中,这个编译过程当然是需要时间的,所以应用程序级别的T-SQL 交给数据库编译以后才执行,更可恶的是,竟然对外部传输来的T-SQL语句不会进行 “过程缓存”,因为他在编译后就立即执行了,而存储过程他就已经预先编译了,也进行了查询的优化了,还会保存在“过程缓存”中,所以推荐使用存储过程。

下面就来展示一个例子:

USE Northwind;

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='London'

GROUP BY C.CustomerId

HAVING COUNT(o.OrderId)>5

ORDER BY NumOrders;

返回结果:

EASTC       8

SEVES       9

BSBEV      10

AROUT     13

上次 就有朋友在留言中提到这个问题 ,下面我们来看看他的执行计划,到底 逻辑处理 和物理处理 有什么不同.我们点击 显示估计的执行计划” ,然后找到 最右边的 Index seek 索引查找,下图

MS SQL Server 2005 物理查询处理中的各个阶段 (二)

这是我切下来的图片,

我们看到 他的Seek 谓词 [Northwind].[dbo].[Customers].City=N’London’

再看看 我们的查询 语句的WHERE 部分

WHERE c.City='London'

完全 符合我在 你真的了解T-SQL逻辑查询吗? 一问中先说到的 第一个阶段 找到FROM 的表,但是又有一点不同,物理查询 他会等到执行CROSS 链接以后的 记录,他会先直接 筛选WHERE 中的记录 等于  3 逻辑 处理阶段 连接和 4个阶段WHERE 合并了.至于 这样有什么好处呢?

我们继续,首先我们分析 WHERE ,我们先考虑一种情况  如果 是按照 逻辑 执行阶段的顺序,CROSS JOIN 下来的 虚拟表 将是非常恐怖的 .可是 MS 的员工 在逻辑阶段 到物理阶段的过程中,肯定会采取一些列手段来优化T-SQL 语句,所以 我们联想到 先执行WHERE 中的 逻辑处理阶段 左表中的 结果 返回

相当于 执行:

USE Northwind;

SELECT C.CustomerId

FROM dbo.Customers AS C

WHERE c.City='London'

 

他返回的结果是:

 

AROUT

BSBEV

CONSH

EASTC

NORTS

SEVES

果然和我们 预想的一样返回的 行数 完全和执行计划中的 估计行数 : 6 行 吻合,

这样执行的结果的好处 ,我们自然可以联想到,6行的结果集 再来 CROSS JOIN 就小多了

,下面我们继续刚才的分析,接着 自然是 Orders 表的链接,

自然 MS SQL Server 2005 物理查询处理中的各个阶段 (二) 启用它的ON  条件, (看看Seek 谓词)

我们再回过来看看 之前说的  物理处理阶段,是不是 完全吻合. 之所以要说明白 逻辑阶段,(说个题外话,有兴趣的朋友可以去看看Algebrizer,他是T-SQL中的 新组件是 绑定的重要功能,我想对高数有研究的朋友可能会喜欢里面的研究和分析.他取代了2000中的Normalizer组件,在物理 逻辑 级别提高了T-SQL 效率.)

对于 后面文章的  优化查询语句 起到了 举足轻重的作用, 讲明了 物理 处理阶段和 逻辑处理阶段 对于 存储引擎是 怎么执行T-SQL 有了一定的了解,才能从原理级别去提高T-SQL ,这也是国内很多同行不曾重视的.当然本文的下一篇将继续我们的研究 -子查询的精要