Reading Query Plans: Stairway to SQL Server Indexes Level 9

阅读查询计划:SQL Server索引9级楼梯

该系列

这篇文章是楼梯系列的一部分:SQL Server索引楼梯

索引是数据库设计的基础,并告诉开发者使用数据库设计者的意图大量。不幸的是,指标往往是后加上的性能问题出现时。在这里是一个简单的文章,应该让任何数据库专业迅速的加快速度与他们系列

在这个楼梯,我们经常说某个执行查询以一定的方式;我们把生成的查询计划来支持我们的声明。估计与实际的查询计划管理工作室的显示可以帮助您确定的利益,或缺乏,你的指标。因此,这一层次的目的是给你的,你可以充分了解查询计划:

  • 验证我们的断言,当你读这楼梯。
  • 确定你的指标有利于您的查询。

有许多文章阅读查询计划,包括MSDN Library中的几个。这不是我们的意图来扩展或替换。事实上,我们将在这个水平,他们很多提供链接/参考。一个好的开始是显示图形执行计划(http://msdn.microsoft.com/en-us/library/ms178071.aspx)。其他有用的资源包括Grant Fritchey的书,SQL执行计划(可用于电子书免费),和Fabiano Amorim的一系列简单的说在你的查询计划输出发现各个运营商的文章(HTTP:/ / www.simple-talk。COM /作者/法比亚诺阿莫林/)。

图形化的查询计划

一个查询计划指令,SQL Server是执行一个查询集。SQL Server Management Studio将显示您在文本、查询计划的图形,或XML格式。例如,考虑下面的简单查询:

选择特徵头衔&# 160接触的人。哪里后缀='小'顺序头衔

此查询的计划可能被视为如图1所示。

<strong>图1–实际查询计划的图形格式</strong>

或者,它可以被看作是文本:

| --排序(按:([中],[人]。[接触],[标题] ASC))


| --聚集索引
扫描(对象:([中],[人]。[接触]。[ pk_contact_contactid ]),
其中:([中],[人]。[接触]。[后缀] = n'jr. '))

或一个XML文件,这样的一个开始:

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

  • 要求图形查询计划,利用管理工作室的SQL编辑器工具栏,它有一个“显示估计的执行计划”和“包括实际的执行计划”按钮。“显示估计的执行计划”选项显示查询计划图立即为选定的TSQL代码,而不执行查询。“包括实际的执行计划”按钮是一个开关,当您选择此选项,您执行的会告诉你一个新的标签的查询计划图的每一批查询,随着结果的消息。这个选项可以在图1所示。
  • 要求文本查询计划,使用设置showplan_text声明。把文字版将把图形版本,将不执行任何您的查询。
  • 查看XML的版本,右键在图形版本,选择“显示执行计划XML”从上下文菜单。

对于这一层次的其余部分,我们专注于图形视图,因为它通常提供的计划最快的理解。查询计划,一张照片通常比一千个字。

阅读图形查询计划

图形查询计划通常是从左到右阅读;最右边的图标(S)表示在一个数据流的第一步。这通常是一堆或索引的访问。你不会看到单词<em>表</em>用在这里;相反,你会看到一<em>堆扫描</em><em>聚集索引扫描</em>或。这是第一个地方看看哪些指标,如果有的话,正在使用。

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

连接操作的箭头代表行,流出来一个运行到下一个。

将鼠标在图标或箭头将导致额外的信息显示。

不想一个操作的一个步骤,这意味着一个操作必须下一个操作之前完成就可以开始。这不一定是真的。例如,当一个WHERE子句进行评估,即当一个<em>过滤器的</em>操作执行,行评价一次;不能一次全部。一排可以移动到下一个操作一行到达过滤操作之前。一<em>种</em>操作,另一方面,必须完成完整的第一行之前可以移动到下一个操作。

使用一些额外的信息

一个图形化的查询计划显示两个潜在的有用的信息,是不是计划本身的一部分;建议指标和每个操作的相对成本。

在上面的例子中,所提出的指标,显示绿色和截断的空间要求,推荐了一个非聚集索引<em>的接触</em>表的<em>后缀</em>柱;包括列<em>标题</em>,<em>FirstName</em>、<em>MiddleName</em>,和<em>姓</em>。

这个计划的每个操作的相对成本告诉我们,排序操作是总成本的5%,而95%的表扫描的工作。因此,如果我们想提高这个查询的性能,我们应该解决的表扫描,不排序;这就是为什么一个指标的建议。如果我们创建推荐的指标,像这样:

创建非聚集索引ix_suffix打开(放)接触的人。后缀包括头衔特徵

然后重新运行查询,我们读取从569下降至3;而新的查询计划,如下图所示,说明了为什么。

新的非聚集索引,其索引键的<em>后缀</em>,有“后缀=“Jr.”条目聚集在一起;因此,减少IO需要检索数据。作为一个结果,排序操作,这是它在以前的计划相同的排序操作,现在代表在查询的总成本的75%,而只有5%的成本,它已经。因此,原计划需要75 / 5 = 15倍量的工作收集相同的信息,目前的计划。

由于我们的WHERE子句仅包括相等运算符,我们甚至可以通过移动标题列为索引键提高我们的指数,像这样:

如果&# 160存在(;选择*sys.indexes
哪里object_id=object_idn'person接触”。姓名=n'ix_suffix”删除索引ix_suffix打开(放)接触的人。
创建非聚集索引ix_suffix打开(放)接触的人。
后缀头衔
包括特徵

现在,需要的条目仍然聚集在索引中,每个簇内,他们是在请求的序列;通过新的查询计划显示,如图2所示。

<strong>图2改造后的非聚集索引的查询计划</strong>

目前的计划显示,排序操作不再需要。在这一点上,我们可以把我们的高效益的覆盖指标。这恢复<em>联系</em>表的方式是当我们开始;这是我们要在我们进入下一个话题。

查看并行流

如果两个流行可以并行处理,他们会彼此上下的图形显示。箭头的相对宽度显示多少行正通过每个流处理。

例如,下面的加入,扩展了以前的查询,包括销售信息:

选择c.lastnamec.firstnamec.middlenameC.标题
h.salesorderidh.orderdate
接触C的人。
加入sales.salesorderheader H打开(放)h.contactid=c.contactid
哪里后缀='小'
顺序头衔

查询计划如图3所示。

<strong>图3–查询计划加入</strong>

在计划一看就告诉我们一些事情:

  • 这两个表同时扫描。
  • 大部分的工作是在扫描表。
  • 多排出来或<em>salesorderheader</em>表出了<em>联系</em>表。
  • 两表不聚为同一序列;因此匹配每个<em>salesorderheader</em>排排的<em>接触</em>将需要额外的努力。在这种情况下,一个<em>哈希匹配</em>操作使用。(更多的散列后。)
  • 要选择的行排序的努力是微不足道的。

即使个别流行可以分成较少的每一行利用并行处理单独的流。例如,如果我们改变到后缀是零以上查询的WHERE子句。

更多的行被返回,为超过95%的<em>接触</em>行有空后缀。新的查询计划反映了这一点,如图4所示。

<strong>图4–并行查询计划</strong>

新计划还表明,增加<em>接触</em>行造成匹配和排序操作成为关键路径查询。如果我们要提高其性能,我们必须首先攻击这两个操作。再次,包括列将帮助索引。

最喜欢的加入,我们的例子,连接两个表通过外键/主键关系。其中的一个表,<em>联系</em>,是先由<em>ContactID</em>,这也正好是其主要的关键。在其他表中,<em>saleorderheader</em> <em>ContactID</em>是外键。自从<em>ContactID</em>是外键,数据访问请求<em>saleorderheader</em> <em>ContactID</em>,比如我们加入的例子,可能是一种常见的业务需求。这些要求都将受益于一个指数<em>的ContactID</em>。

每当你的索引外键列,总是问自己,如果有,柱应补充,包括列的索引。在我们的例子中,我们有一个查询而不是一个家庭支持的查询。因此,我们只包括将<em>OrderDate</em>列。支持一个家庭的<em>ContactID</em>型查询<em>saleorderheader</em>表格,我们会有更多的<em>saleorderheader</em>列在索引中,根据需要,以支持那些额外的查询。

我们的CREATE INDEX语句:

创建非聚集索引ix_contactid打开(放)sales.salesorderheaderContactID包括訂單日期

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

<strong>图5–计划一个连接查询与支撑指标对每个表</strong>

因为现在正在进行的输入流的谓词连接柱、<em>ContactID</em>;加入部分的查询可以做到不裂流无散列;从而减少什么是26 + 5 + 3 = 34%的工作负荷降至4%的工作负荷。

整理、预存和散列

很多查询操作要求数据分组之前,可以进行的操作。这些包括不同,联盟(这意味着不同),组(及其各种聚合函数),并加入。通常情况下,SQL Server将使用三种方法来实现这个分组,其中第一个需要你的帮助:

  • 高兴地发现数据已经被预设为分组序列。
  • 组数据进行<em>散列</em>运算。
  • 排序数据的分组序列。

它的

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

散列

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

所需的哈希信息存储量是所需的基团的数目直接相关。因此,哈希需要解决:

选择性别计数(*)
newyorkcitycensus
性别

Would require very little memory, for there would be only two groups; Female and Male , regardless of the number of input rows.另一方面:

选择计数(*)
newyorkcitycensus

会导致群体的一个巨大的数字,每个都需要回忆自己的空间;可能消耗大量内存,哈希成为解决查询一个不受欢迎的技术。

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

排序

如果数据没有预设(索引),如果SQL Server认为散列不能高效完成,SQL Server将数据排序。这通常是最理想的选择。因此,如果一个<em>排序</em>图标出现在早期的计划,看看你可以提高你的索引。如果<em>排序</em>图标出现在年底的计划,这可能意味着SQL Server排序最后输出成序列要求ORDERBY子句;这种序列与序列被用来解决查询的连接、分组、和工会。通常,很少有你可以避免这一点的那种。

结论

一个查询计划告诉你的方法,SQL Server打算使用或已经使用,执行一个查询。它是通过详细的操作,将被使用,从操作的行的操作流程,和并行性参与。

  • 你把这个信息作为一个文本,图形,或XML显示。
  • 图形计划显示每个操作的相关工作负荷。
  • 图形化的计划可能会建议一个索引,提高查询性能。
  • 理解查询计划将帮助你评估和优化你的指标设计。
posted @ 2017-12-06 10:00  wllw6  阅读(77)  评论(0编辑  收藏  举报