SQL执行计划解析(2)- 基本查询的图形执行计划(中)

2.表连接(Table join)

到目前为止我们都是在和单个表打交道,下边我们看下查询中的连接。下边这个查询获取雇员信息,把FirstName和LastName连接起来,这样返回的信息显得更为友好。

SELECT 
  e.[Title],
  a.[City],
  c.[LastName] + ', ' + c.[FirstName] AS EmployeeName
FROM 
  [HumanResources].[Employee] e
JOIN 
  [HumanResources].[EmployeeAddress] ed 
ON 
  e.[EmployeeID] = ed.[EmployeeID]
JOIN 
  [Person].[Address] a 
ON 
  [ed].[AddressID] = [a].[AddressID]
JOIN 
  [Person].[Contact] c 
ON 
  e.[ContactID] = c.[ContactID];

 执行计划如图

图2-12

这个查询中出现了多个的处理步骤,每个步骤的开销也不同,它们在执行树中从右到坐一步一步累计起来。其中3个开销最大的操作分别是

1.对Person.Address表的索引扫描(Index Scan),45%

2.HumanResource.EmployeeAddress表和Person.Address表之间的Hash Match Join操作,28%

3.Person.Contact表上的聚集索引扫描,17%

右上角的是对HumanResource.EmployeeAddress表的索引扫描,它的下边就是对Person.Address表的索引扫描,也就是我们的开销最大的运算符。看下ToolTip,如图2-13,我们可以看到这是对索引IX_Address_AddressLine1_AddressLine2_City_StateProvinceID_PostalCode执行的扫描,存储引擎遍历了19614行的数据来找到我们需要的。

图2-13

如Output list里所示,查询优化器需要AddressId列和City列。查询优化器按照表中的索引和列的可选择性进行计算,它认为最好的方式就是遍历索引。遍历19614行的数据的开销占据了总开销的45%。
0.180413仅仅是个内部计算出的数字,优化器用于衡量各个操作的相对开销,这个数字越低操作的效率越高。

Hash Match Join

继续上边的例子,这两个索引扫描的输出通过hash match join组合起来。

在我们讨论Hash Match Join是什么之前,需要了解两个概念,Hash运算(即散列算法) 和Hash表。

Hash运算是一种编程技术,用来把数据转换为符号形式,使数据可以更容易更快速地被检索。例如,表中的一行数据,可以通过程序转化为一个唯一的值,这个值就代表了这行数据的内容。这和数据加密很类似,一个hash值同样也可以被转换回原始数据。

Hash表是一个数据结构,它把所有的元素都切分成同等大小的“类”或“块”,允许对这些元素的快速访问。hash函数决定了元素应该进入哪个“块”。例如,你可以从表里取出一行数据,将其转换为hash值,然后将hash值存入hash表。

Hash Match Join 发生时,Sql Server连接一大一小两张表,对小表里的数据行进行hash运算,将生成的hash值插入到hash表里,然后遍历大表里的数据,每次取出一行在hash表里寻找匹配的行。对小表进行hash运算是为了降低hash表的大小,hash值可以进行快速的比较。如果两张表都很大,那么hash match jion和其他类型的join比起来就非常低效。

Hash Match Join对大数据集尤其是其中一个表比另外的一个小很多的时候效率很高。对表没有按照join列排序或者表中没有可用索引的情况,hash match join也是很有效的方式。

Hash Match Join的出现也可能意味着存在更高效的连接方式(Nested Loop或Merge),这可能是以下原因造成的:
  1.索引缺失或者索引不正确
  2.where语句缺失
  3.where语句里有对索引列的计算或转换使得索引失效
在这些情况下,优化器认为Hash Match Join是连接两张表的最高效的方式,但是有可能可以通过增加索引、或者增加where语句来减少数据量等方式获得更高效的查询。

聚集索引查找(Clustered Index Seek)

接下来我们看占用17%的操作,是对Person.Contact表上的PK_Contact_ContactID聚集索引查找,对于这个表来说PK_Contact_ContactID既是主键又是聚集索引。

图2-15

从Seek Predicates节可以看出,这个操作直接将HumanResources.Employee表和Person.Contact表的ContactID列进行连接。

Nested Loop Join(嵌套循环连接)

图2-16

顾名思义,Nested Loop Join这个操作使用嵌套双层循环,在我们这个计划里下边这个(17%那个)运算符的结果在外层。由于两个数据集都很小,所以这是个很高效的操作。
只要内层数据集小,外层数据集(小不小不要紧)有索引的情况下,Nested Loop Join是一种非常高效的连接机制。除非数据集超大,这种连接方式应该是你最希望看到的连接方式。

标量计算(Compute Scarlar)

图2-17

标量计算表示此操作产生了一个标量值,通常是通过计算。我们这个例子中,假名EmployeeName组合了LastName和FirstName并用逗号连接。

 

Merge Join

除了Hash Match 和Nested Loop外,还有一种连接即Merge Join。执行以下查询。

SELECT 
  c.CustomerID
FROM 
  Sales.SalesOrderDetail od
JOIN 
  Sales.SalesOrderHeader oh
ON 
  od.SalesOrderID = oh.SalesOrderID
JOIN S
  ales.Customer c
ON 
  oh.CustomerID = c.CustomerID

 执行计划如图

图2-18

使用Merge Join连接的两张表必须是按照连接列预先排序好了的,这中情况下Merge Join是一种高效的连接方式。如果连接的表没有按照连接列预先排序的话,查询优化器要么先排序再执行Merge

 Join, 或者执行效率稍低些的Hash Match Join。

PS:以前做cobol时处理数据的一种方式,估计原理是一样的。有两组数据,都是排好序的,假设是按某个字段从小到大。设两个指针分别代表左右两个数据的当前记录位置,比较当前位置的数据大小,如果左边的小右边大,那么左边的指针向前移动一位,如果右边的小左边的大,那么右边的指针向前移动一位,如果一样大,那么这是匹配的两条数据,左右同时向前移动一位。这只是连接列的值唯一的情形,也可能是多对多的匹配,当多对多匹配时,Merge Join就必须使用cache了,原理应该是这样子,这样就避免了双层循环,所以如果是排好序的两张表连接,Merge Join的效率应该是最高的。

posted @ 2011-11-02 14:04 chouyuu 阅读(1392) 评论(0) 推荐(0) 编辑

SQL执行计划解析(2)- 基本查询的图形执行计划(上)

摘要: 某种程度上,学习阅读图形执行计划和学习一门新语言很类似。不同之处是这门语言是基于图标的,而且单词(图标)非常少。每个图标代表了一个操作符,本章里,“图标”和“操作符”可以互换地使用。前边一章我们遇到了两个操作符(select和table scan),实际上总共有79个,好在我们不需要全部学会才能开始阅读执行计划,大多数查询只用到了其中的一小部分。如果遇到了我们没有提到的图标,参阅http://msdn2.microsoft.com/en-us/library/ms175913.aspx图形执行计划里有4中不同类型的操作符:逻辑和物理操作符(logical and physical operat 阅读全文
posted @ 2011-09-07 11:54 chouyuu 阅读(2104) 评论(1) 推荐(1) 编辑

SQL执行计划解析(1)- 执行计划基础(下)

摘要: Getting Started如果你不是sysadmin、dbcreator、db_owner,那么你需要权限查看执行计划GRANT SHOWPLAN TO [username]第一个例子非常简单,打开management studio,键入以下查询SELECT *FROM [dbo].[DatabaseLog];点击动作条上Display estimated Execution Plan按钮,就看到了我们的第一个预估执行计划图1-1我们稍后再加以解释,现在我们再抓一个实际的执行计划,和预估的执行计划不同,实际的执行计划并不代表优化器的计算结果,而是代表了查询执行时实际发生的事情,通常两者是一 阅读全文
posted @ 2011-09-06 09:46 chouyuu 阅读(3593) 评论(1) 推荐(1) 编辑

SQL执行计划解析(1)- 执行计划基础(上)

摘要: 本章的目标是使你能够通过图形、文本以及xml方式捕获实际的和预估的执行计划,并且理解如何解释它们的基础知识。 1、查询优化器(query optimizer)简介 2、实际的(Actual)和预估的(Estimated)执行计划 3、捕获和解释不同的可视执行计划 4、自动捕获执行计划 阅读全文
posted @ 2011-08-29 14:06 chouyuu 阅读(1783) 评论(0) 推荐(1) 编辑

MongoDB权威指南(7)- Administration

摘要: 本章从开发者视角切换到管理员视角,讨论了mongoDB管理上的常见任务,包括以下小节 1.启动和停止mongoDB 2.监控 3.安全和认证 4.备份和修复 阅读全文
posted @ 2011-07-26 15:34 chouyuu 阅读(4225) 评论(1) 推荐(2) 编辑

MongoDB权威指南(6)- Advanced Topics

摘要: 除了前边几章的内容之外,mongoDB还提供了一些高级功能,本节包括以下小节 1.数据库命令 2.Capped Collections 3.GridFS 文件存储 4.服务器端脚本 5.数据库引用 阅读全文
posted @ 2011-07-22 10:42 chouyuu 阅读(3226) 评论(0) 推荐(0) 编辑

MongoDB权威指南(5)- Aggregation

摘要: 除了基本的查询功能外,mongoDB还提供了聚合工具,从简单的计数到使用MapReduce进行复杂数据的分析等。本章包含以下小节: 1.count 2.distinct 3.group 4.MapReduce 阅读全文
posted @ 2011-07-14 15:44 chouyuu 阅读(5648) 评论(0) 推荐(0) 编辑

MongoDB权威指南(4)- Indexing

摘要: 索引是提高查询速度的方式。本节包括: 1.索引简介 2.唯一索引 3.使用explain和hint 4.索引管理 5.地理空间索引 阅读全文
posted @ 2011-07-08 10:43 chouyuu 阅读(2343) 评论(0) 推荐(0) 编辑

MongoDB权威指南(3)- Querying

摘要: 本节介绍了查询的详细信息,包括以下小节: 1.find方法简介 2.查询条件 3.特殊类型查询 4.游标 阅读全文
posted @ 2011-07-04 15:49 chouyuu 阅读(4566) 评论(0) 推荐(0) 编辑

MongoDB权威指南(2)-Creating,Updating and Deleting Documents

摘要: 本章节介绍了各种写操作,包括以下小节: 1.插入和保持document 2.删除document 3.更新document 4.Upsert 5.更新多个document 6.返回被更新的document 7.The Fastest Write This Side of Mississippi 阅读全文
posted @ 2011-06-29 16:53 chouyuu 阅读(2642) 评论(0) 推荐(0) 编辑
< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

统计

点击右上角即可分享
微信分享提示