- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
ISQLServer调优系列基础篇常用运算符总结
SQL Server调优系列基础篇(常用运算符总结)2014/12/12 ·?IT技术?·?SQL Server,?数据库分享到:6原文出处:?指尖流淌-吴学雷的博客?前言上一篇我们介绍了如何查看查询计划,本篇将介绍在我们查看的查询计划时的分析技巧,以及几种我们常用的运算符优化技巧,同样侧重基础知识的掌握。通过本篇可以了解我们平常所写的T-SQL语句,在SQL Server数据库系统中是如何分解执行的,数据结果如何通过各个运算符组织形成的。技术准备基于SQL Server2008R2版本,利用微软的一个更简洁的案例库(Northwind)进行解析。一、数据连接数据连接是我们在写T-SQL语句的时候最常用的,通过两个表之间关联获取想要的数据。SQL Server默认支持三种物理连接运算符:嵌套循环连接、合并连接以及哈希连接。三种连接各有用途,各有特点,不同的场景会数据库会为我们选择最优的连接方式。?a、嵌套循环连接(nested loops join)嵌套循环连接是最简单也是最基础的连接方式。两张表通过关键字进行关联,然后通过双层循环依次进行两张表的行进行关联,然后通过关键字进行筛选。可以参照下图进行理解分析其实嵌套扫描是很简单的获取数据的方式,简单点就是两层循环过滤出结果值。我们可以通过如下代码加深理解1234for each row R1 in the outer table for each row R2 int the inner table if R1 join with R2 return (R1,R2)举个列子1234SELECT o.OrderIDFROM Customers C JOIN Orders OON C.CustomerID=O.CustomerIDWHERE C.City=N#039;London#039;以上这个图标就是嵌套循环连接的图标了。而且解释的很明确。这种方法的消耗就是外表和内表的乘积,其实就是我们所称呼的笛卡尔积。所以消耗的大小是随着两张表的数据量增大而增加的,尤其是内部表,因为它是多次重复扫描的,所以我们在实践中的采取的措施就是减少每个外表或者内表的行数来减少消耗。对于这种算法还有一种提高性能的方式,因为两张表是通过关键字进行关联的,所以在查询的时候对于底层的数据获取速度直接关乎着此算法的性能,这里优化的方式尽量使用两个表关键字为索引查询,提高查询速度。还有一点就是在嵌套循环连接中,在两张表关联的时候,对外表都是有筛选条件的,比如上面例子中【WHERE C.City=N’London’】就是对外表(Customers)的筛选,并且这里的City列在该表中存在索引,所以该语句的两个子查询都为索引查找(Index Seek)。但是,有些情况我们的查询条件不是索引所覆盖的,这时候,在嵌套循环连接下的子运算符就变成了索引扫描(Index scan)或者RID查找。举个例子1234SELECT E1.EmployeeID,COUNT(*)FROM Employees E1 JOIN Employees E2ON E1.HireDatelt;E2.HireDateGROUP BY E1.EmployeeID以上代码是从职工表中获取出每位职工入职前的人员数。我们看一下该查询的执行计划这里很显然两个表的关联通过的是HireDate列进行,而此列又不为索引项所覆盖,所以两张表的获取只能通过全表的聚集索引扫描进行,如果这两张表数据量特别大的话,无疑又是一个非常耗性能的查询。通过文本可以看出,该T-SQL的查询结果的获取是通过在嵌套循环运算符中,对两个表经过全表扫描之后形成的笛卡儿积进行过滤筛选的。这种方式其实不是一个最优的方式,因为我们获取的结果其实是可以先通过两个表过滤之后,再通过嵌套循环运算符获取结果,这样的话性能会好很多。我们尝试改一下这个语句1234567SELECT E1.EmployeeID,ECNT.CNT FROM Employees E1 CROSS APPLY( SELECT COUNT(*) CNT FROM Employees E2 WHERE E1.HireDatelt;E2.HireDate)ECNT通过上述代码查询的结果项,和上面的是一样的,只是我们根据外部表的结果对内部表进行了过滤,这样执行的时候就不需要获取全部数据项了。我们查看下文本执行计划我们比较一下,前后两条语句的执行消耗,对比一下执行效率执行时间从1秒179毫秒减少至93毫秒。效果明显。对比CPU消耗、内存、编译时间等总体消耗都有所降低,参考上图。所以对嵌套循环连接连接的优化方式就是集中在这几点:对两张表数据量的减少、连接关键字上建立索引、谓词查询条件上覆盖索引最好能减少符合谓词条件的记录数。?b、合并连接(mer
文档评论(0)