翻译(十一) ——Reading Query Plans: Stairway to SQL Server Indexes Level 9

Reading Query Plans: Stairway to SQL Server Indexes Level 9

By David Durant, 2011/10/05

原文链接:http://www.sqlservercentral.com/articles/Stairway+Series/72441/

The Series

本文是阶梯系列的一部分:SQL Server索引的阶梯。

索引是数据库设计的基础,并告诉开发人员使用数据库大量关于设计者的意图。不幸的是,当性能问题出现时,索引常常会作为事后考虑添加。这里最后是一系列简单的文章,应该能让数据库专业人员快速地与它们同步。

在整个步骤中,我们经常声明某个查询以某种方式执行;我们引用生成的查询计划来支持我们的语句。管理库显示估计和实际查询计划,可以帮助您确定索引的好处或不足。因此,这个级别的目的是让您对查询计划有足够的了解:

当你阅读这个阶梯时,验证我们的断言。

确定索引是否有利于查询。

有许多文章阅读查询计划,包括MSDN Library中的几个。我们不打算扩展或替换它们。事实上,我们将在这个级别为他们中的许多人提供链接/引用。开始的好地方是显示图形执行计划。(http://msdn.microsoft.com/en-us/library/ms178071.aspx). 其他有用的资源包括Grant Fritchey的书,SQL执行计划(可用于电子书免费),和Fabiano Amorim的一系列简单的对话篇关于各运营商发现您的查询计划的输出(http://www.simple-talk.com/author/fabiano-amorim/).

 

Graphical Query Plans

  查询计划是SQLServer执行查询时所遵循的一组指令。SQLServer将以文本、图形或XML格式显示对您的查询计划。例如,考虑下面的简单查询:

    SELECT LastName, FirstName, MiddleName, Title 
FROM Person.Contact
WHERE Suffix = ‘Jr.‘
ORDER BY Title

这个查询的计划可以如图1所示。

1 -图形格式的实际查询计划

或者,可以将其视为文本:

|--Sort(ORDER BY:([AdventureWorks].[Person].[Contact].[Title] ASC))

|--Clustered Index
Scan(OBJECT:([AdventureWorks].[Person].[Contact].[PK_Contact_ContactID]),
WHERE:([AdventureWorks].[Person].[Contact].[Suffix]=N‘Jr.‘))

或者作为一个XML文档,从这样开始:

查询计划的显示可以如下所示要求:

要请求图形化查询计划,请使用管理室的SQL编辑器工具栏,该工具栏同时具有“显示估算执行计划”和“包含实际执行计划”按钮。“显示估计的执行计划”选项显示查询计划图立即为选定的TSQL代码,而不执行查询。“包含实际执行计划”按钮是一个开关,一旦您选择了这个选项,您执行的每个查询批将在一个新选项卡中显示查询计划图,以及结果和消息。这个选项可以在图1中看到。

要求文本查询计划,使用设置showplan_text声明。打开文本版本将关闭图形版本,不会执行任何查询。

要查看XML版本,在图形版本中右击,并从上下文菜单中选择“显示执行计划XML”。

对于这个级别的其余部分,我们专注于图形视图,因为它通常提供对计划的最快的理解。对于查询计划,一个图片通常比一千个词更好。

 

Reading Graphical Query Plans

图形查询计划通常从右向左读取;右最图标表示数据收集流中的第一步。这通常是访问堆或索引。您不会看到这里使用的字表;相反,您将看到集群索引扫描或堆扫描。这是第一个查看哪些索引(如果有的话)正在使用的地方。

图形化查询计划中的每个图标表示一个操作。在可能的图标的更多信息,参见图形执行计划在http://msdn.microsoft.com/en-us/library/ms175913.aspx图标

 

 

连接操作的箭头表示行,从一个操作流出并进入下一个操作。

将鼠标放在图标或箭头上会导致显示更多信息。

不要把操作看作步骤,因为这意味着在下一个操作开始之前必须完成一个操作。这不一定是真的。例如,当对WHERE子句进行求值时,也就是说,当执行筛选器操作时,一次一行求值,而不是一次求值。在后续行到达筛选器操作之前,一行可以移动到下一操作。另一方面,排序操作必须在第一行移动到下一操作之前全部完成。

 

Using Some Additional Information

   图形化查询计划显示了两个可能有用的信息,这些信息不是计划本身的一部分;建议的索引和每个操作的相对成本。

在上面的例子中,所提出的指标,显示绿色和空间要求截断,建议联系表的后缀列的非聚集索引;包括标题、FirstNameMiddleName列,和姓。

这个计划的每个操作的相对成本告诉我们,排序操作占总成本的5%,而表扫描是工作的95%。因此,如果我们想改进这个查询的性能,我们应该处理表扫描,而不是排序,这就是为什么建议索引的原因。如果我们创建推荐索引,像这样:

CREATE NONCLUSTERED INDEX IX_Suffix ON Person.Contact
(
Suffix
)
INCLUDE ( Title, FirstName, MiddleName, LastName )

然后重新运行查询,我们的读取量从569下降到3;新的查询计划如下所示。

新的非聚集索引,其索引键后缀,有“后缀=Jr.”条目聚集在一起;因此,在IO需要检索数据还原。因此,排序操作与前一个计划中的排序操作相同,现在代表了查询总成本的75%以上,而不是原来的5%。因此,原始计划需要75/5倍于当前计划收集相同信息的工作量的15倍。

由于我们的WHERE子句只包含一个相等运算符,因此我们可以通过将标题列移动到索引键来改进索引:

IF  EXISTS (SELECT * FROM sys.indexes
WHERE OBJECT_ID = OBJECT_ID(N‘Person.Contact‘)

AND name = N‘IX_Suffix‘)
DROP INDEX IX_Suffix ON Person.Contact
CREATE NONCLUSTERED INDEX IX_Suffix ON Person.Contact
(
Suffix, Title
)
INCLUDE ( FirstName, MiddleName, LastName )

现在,所需的条目仍然在索引中聚集在一起,并且在每个集群中都在请求的序列中;如新的查询计划所示,如图2所示。

2查询计划重建非聚簇索引后

现在计划表明不再需要排序操作。在这一点上,我们可以放弃高收益的覆盖指数。这将使联系人表恢复到我们开始时的状态;当我们进入下一个话题时,这是我们希望它处于的状态。

 

Viewing Parallel Streams

    如果可以并行处理两行行,它们将在图形显示中彼此上下显示。箭头的相对宽度指示通过每个流处理的行数。

例如,下面的连接将前面的查询扩展为包含销售信息:

SELECT C.LastName, C.FirstName, C.MiddleName, C.Title
, H.SalesOrderID, H.OrderDate
FROM Person.Contact C
JOIN Sales.SalesOrderHeader H ON H.ContactID = C.ContactID
WHERE Suffix = ‘Jr.‘
ORDER BY Title

查询计划如图3所示。

3 -连接的查询计划

快速看一下这个计划会告诉我们一些事情:

两个表同时扫描。

大部分的工作都花在扫描桌子上。

多排出来或salesorderheader表超过了接触表。

两表不聚为同一序列;因此每个salesorderheader行行匹配的接触将需要额外的努力。在这种情况下,使用哈希匹配操作。(稍后再讨论散列)。

排序所选行所需的努力可以忽略不计。

即使是单独的行行也可以分解成单独的行,以利用并行处理。例如,如果我们将上面查询中的WHERE子句改为后缀为null的地方。

将返回更多的行,因为95%的联系人行有一个空后缀。新的查询计划反映了这一点,如图4所示。

4 -一个并行查询计划

新计划还向我们表明,接触行数的增加导致匹配和排序操作成为该查询的关键路径。如果我们需要提高它的性能,我们必须首先攻击这两种操作。同样,包含列的索引将有助于。

和大多数连接一样,我们的示例通过外键/主键关系连接两个表。其中的一个表,联系,是先由ContactID,这也正好是其主要的关键。在其他表中,saleorderheader ContactID是外键。自从ContactID是外键,用于数据访问的saleorderheader ContactID请求,如我加入的例子,可能是一种常见的业务需求。这些请求将从索引ContactID效益。

每当您对外键列进行索引时,总是问自己,如果列中包含了列,那么应该添加哪些索引。在我们的例子中,我们只有一个查询,而不是一个支持查询的家庭。因此,我们只包括将OrderDate列。支持一个家庭的ContactID导向对saleorderheader表查询,我们将包括在索引中,列的更多saleorderheader的需要,以支持那些额外的查询。

我们的创建索引语句是:

CREATE NONCLUSTERED INDEX IX_ContactID ON Sales.SalesOrderHeader
(
ContactID
)
INCLUDE ( OrderDate )

而新计划的执行我们的salesorderheader和联系信息加入如图5

5 -计划在每个表上有一个支持索引的连接查询

由于输入流现在是由谓词连接柱、ContactID;测序加入部分的查询可以做到不裂流无散列;从而减少26 + 5 + 3 = 34%的工作负载下4%的工作负载是什么。

 

Sorting, Presorting and Hashing

许多查询操作要求在执行操作之前将数据分组。这些包括明确的,联盟(这意味着不同),按组(及其各种聚合函数),并加入。通常,SQL Server将使用三种方法中的一种来实现这种分组,第一种方法需要您的帮助:

高兴地发现数据已经被预设为分组序列。

通过执行哈希操作将数据分组。

将数据排序到分组序列中。

 

Presorting

指标是你的预存数据;即在经常需要对SQL Server提供的数据序列。这就是为什么非聚集索引的创建,每个包含包含性列,得益于我们之前的例子。事实上,如果将鼠标放在最近查询中的合并连接图标上,则短语将使用两个适当排序的输入流匹配行,利用它们的排序顺序。将出现。这将告诉您两个表/索引的行是使用内存和处理器时间的绝对最小值来连接的。相应排序的输入是一个精彩的短语看到当鼠标查询计划的图标,它验证了你选择的指标。

 

Hashing

如果输入的数据不是理想的序列,SQLServer可以使用哈希操作对数据分组。哈希是一种可以使用大量内存的技术,但通常比排序效率更高。当执行不同,联盟,加入行动,散列在单个行可以通过下一步操作无需等待所有的输入行被哈希排序优势。但是,在计算分组聚集时,必须在将所有聚合值传递给下一个操作之前读取所有输入行。

散列信息所需的内存量与所需的组数直接相关。因此需要解析散列:

SELECT Gender, COUNT(*)
FROM NewYorkCityCensus
GROUP BY Gender
只需要很少的内存,因为只有两个组:女性和男性,不管输入行数。另一方面:
SELECT LastName, FirstName, COUNT(*)
FROM NewYorkCityCensus
GROUP BY LastName, FirstName

将导致大量的组,每个组都需要在内存中拥有自己的空间;可能消耗了太多的内存,哈希成为解决查询的不可取的技术。

更多的查询计划哈希,访问http://msdn.microsoft.com/en-us/library/ms189582.aspx

 

Sorting

如果数据没有预设(索引),如果SQL Server认为散列不能高效完成,SQL Server将数据排序。这通常是最不可取的选择。因此,如果在计划早期出现排序图标,请检查是否可以改进索引。如果Sorticon出现在计划结束时,这可能意味着SQL ServerORDER BY子句的请求序列排序的最终输出;这种序列与序列被用来解决查询的连接、分组、和工会。通常,在这一点上你可以做些什么来避免这种排序。

 

Conclusion

查询计划显示SQL Server打算使用或使用的方法来执行查询。它通过详细说明将要使用的操作、从操作到操作的行流以及所涉及的并行性。

您将此信息视为文本、图形或XML显示。

图解显示每个操作的相对工作负荷。

图形化计划可能会提供一个索引来提高查询的性能。

理解查询计划有助于评估和优化索引设计。

时间: 2024-10-12 19:39:36

翻译(十一) ——Reading Query Plans: Stairway to SQL Server Indexes Level 9的相关文章

翻译(九)——Clustered Indexes: Stairway to SQL Server Indexes Level 3

原文链接:www.sqlservercentral.com/articles/Stairway+Series/72351/ Clustered Indexes: Stairway to SQL Server Indexes Level 3 By David Durant, 2013/01/25 (first published: 2011/06/22) The Series 本文是阶梯系列的一部分:SQL Server索引的阶梯. 索引是数据库设计的基础,并告诉开发人员使用数据库大量关于设计者的

Stairway to SQL Server Replication: Level 1 - Introduction to SQL Server Replication翻译,合并截图翻译

SQL Server复制的阶梯:第1级 -  SQL Server复制简介 网址:http://www.sqlservercentral.com/articles/Stairway+Series/72274/ 作者: Sebastian Meine, 2012/12/26 该系列介绍:本文是Stairway系列文章的一部分:SQL Server复制的阶梯 SQL复制可以解决运行数据库驱动的应用程序时的许多问题.发布/订阅者的模型并不容易理解,脚本和监视复制系统的复杂性需要一些思考.最后,这一系列

#翻译#通往SQL Server安全级别2的阶梯:身份验证; 唐?吉利; 原文链接:Stairway to SQL Server Security Level 2: Authentication http://www.sqlservercentral.com/articles/Stairway+Series/109975/

这篇文章是楼梯系列的一部分:通往SQL Server安全的阶梯 SQL Server拥有您需要的所有东西来保护您的服务器和数据以抵御今天的复杂攻击.但是在您能够有效地使用这些安全特性之前,您需要了解您所面临的威胁和一些基本的安全概念.第一个阶梯级提供了一个基础,这样您就可以充分利用SQL服务器的安全特性,而不必浪费时间来防止对数据的特定威胁. 身份验证是验证一个君主国--一个需要访问SQL Server数据库的用户或进程--是谁或它声称是什么的过程.一个主体需要唯一的标识,以便SQL Serve

SQL Server索引进阶:第九级,读懂执行计划

原文地址: Stairway to SQL Server Indexes: Level 9,Reading Query Plans 本文是SQL Server索引进阶系列(Stairway to SQL Server Indexes)的一部分. 在这个系列中,我们经常会以特定的方式执行特定的查询.我们引用生成的执行计划来支持我们的论调.SQL Server管理器显示的预估的和实际的查询计划,可以帮助我们确定索引的好处,以及其中的缺陷.因此,本文的主要目的是给你一些关于执行计划的充分的理解: 验证

SQL Server索引进阶:第十级,索引内部结构

原文地址: Stairway to SQL Server Indexes: Level 10,Index Internal Structure 本文是SQL Server索引进阶系列(Stairway to SQL Server Indexes)的一部分. 在之前的级别中,我们从逻辑的角度介绍索引,集中于它们能为我们做什么.现在,是时候从物理的角度,并且检查一下索引的内部结构,从理解索引的内部结构,引导我们理解索引在上层做的工作.通过索引的结构,它是如何维护的,你可以理解在进行插入,更新,删除的

SQL Server索引进阶:第一级,索引简介

By David Durant, 2014/11/05 (first published: 2011/02/17) 原文地址: Stairway to SQL Server Indexes: Level 1, Introduction to Indexes 本文是SQL Server索引进阶系列(Stairway to SQL Server Indexes)的一部分. 索引是数据库设计的基础,向开发者显示了使用数据库大量数据库设计者的意图.不幸的是,索引大部分时候是在出现性能问题的时候,才被事后

SQL Server中关于基数估计如何计算预估行数的一些探讨

关于SQL Server 2014中的基数估计,官方文档Optimizing Your Query Plans with the SQL Server 2014 Cardinality Estimator里有大量细节介绍,但是全部是英文,估计也没有几个人仔细阅读.那么SQL Server 2014中基数估计的预估行数到底是怎么计算的呢? 有哪一些规律呢?我们下面通过一些例子来初略了解一下,下面测试案例仅供参考,如有不足或肤浅的地方,敬请指教! 下面实验测试的环境主要为SQL Server 201

第16/24周 SQL Server 2014中的基数计算

大家好,欢迎回到性能调优培训.上个星期我们讨论在SQL Server里基数计算过程里的一些问题.今天我们继续详细谈下,SQL Server 2014里引入的新基数计算. 新基数计算 SQL Server 2014里一个增强是新的基数计算.上个星期你已经学到老基数计算有些限制,会生成错误的估计,这会导致不好的执行计划表现.截至SQL Server 2012,你一直在使用自SQL Server 7.0引入的基数计算. 当然,几年来也有很多问题被修正,但默认它们都没启用的——你需要启用SQL Serv

【译】SQL Server索引进阶第八篇:唯一索引

原文:[译]SQL Server索引进阶第八篇:唯一索引     索引设计是数据库设计中比较重要的一个环节,对数据库的性能其中至关重要的作用,但是索引的设计却又不是那么容易的事情,性能也不是那么轻易就获取到的,很多的技术人员因为不恰当的创建索引,最后使得其效果适得其反,可以说"成也索引,败也索引".     本系列文章来自Stairway to SQL Server Indexes,翻译和整理后发布在agilesharp和博客园,希望对广大的技术朋友在如何使用索引上有所帮助.   唯一