SQL Server执行计划详细介绍(二)

我们在前文SQL Server执行计划详细介绍(一)中详细介绍了执行计划中的数据访问操作和书签查询,本文继续来介绍聚合操作。

聚合(Aggregation

聚合一般用在一些总结的操作上,比如我们常见的求和或者平均数等操作(SUM, AVG, MAX等),在SQL Server中有两种聚合的操作:流聚合(Stream Aggregate)和哈希聚合(Hash Aggregate)

排序和哈希

在具体介绍聚合操作之前,简单提一下排序和哈希,流聚合其实是要求数据是有序的,我们可以使用已存在的index或者就显式地进行排序操作。当然排序会使用到memory,假如可用的memory不足,它会使用tempdb,这种情况下必然也就会影响到performance了。同样的,哈希会在哈希聚合中使用,我们需要在memory中建立一个哈希表。无论排序还是哈希操作都是一个block的操作,也就是说我们必须等他们全部完成了才能进行下一步的操作。

流聚合

  • AVG

首先我们来看一下流聚合的操作例子,我们来看一个ListPrice的平均值:

我们查看Stream Aggregateproperty(鼠标右击选择属性),可以看到整个Stream Aggregate的过程,他其实是先求的countSUM,他们分别保存在Expr1003Expr1004中。

在随后的Compute Scalar中,会check count数目(本例就是Expr1003)是不是0,如果是0就直接返回null,否则就用sum除以count来得到平均数。具体看下图Compute Scalar中的属性:

  • Group by

下面我们继续来看一个Group by的例子:

Group by总是要求输入是一个有序的值,所以我们可以看到在我们的例子这种会先根据ProductLine进行排序,在排序之后,我们就可以发现同样值的ProductLine就在一起了,那么在Stream Aggregate中计算count的时候的就很简单了,直接一条一条判断就可以了,是一个group的就加一,不是就新建一行。具体的Stream Aggregate操作如下图所示:

就像我们之前提到的,Group by其实是可以利用index来进行的,这样就不需要额外的排序操作了:

这个例子中,salesorderid其实是一个index,我们知道它肯定是排好序的,所以我们不需要额外的排序操作。

哈希聚合

哈希聚合一般会用在数据量比较大的表格中,当我们groupcolumn是没有index的,并且输出的结果行也比较少的时候,我们会发现去排序整个表不太值得,我们就有可能会决定不去对整个表排序,而使用哈希聚合,见下面这个例子,我们在revisionNumber这一列上没有index,整个表有三万多行,但聚合后只有两行输出:

哈希聚合就是首先在内存中创建一个哈希表,因为我们之前也会遍历整个表,所以在遍历的时候,我们就会为每一行创建哈希key,这个哈希key可以在hash match的属性表中看到,我们这里很明显哈希key就是revisionnumber,然后每一行就会看对应的哈希值是不是已经在表中存在了,若是不存在就加一行。整个哈希表每一个哈希值一行,这也是为什么我们会说在输出(其实就是哈希值)行比较少的情况下选择会比较好,因为这样我们所建的哈希表就会相对较小。

就像我们上面提到的,哈希聚合只是说在你没有排序的情况下会使用,假如我们创建了一个index,这个时候,我们可能就直接选择一个流聚合而不需要再使用哈希聚合了,如下所示:

在继续之前让我们先把上面创建的indexdrop掉:

我想这个时候,你可能会问假如我们的表格没有排序,但是我们的query中有显式的要求排序,这个时候我们排序还是不排序呢,其实这时候我们有两种选择,一种选择就是和之前的流聚合一样,就是先排序,然后再流聚合。但是也有一个可能就是我们会先进行哈希聚合,然后再对结果进行排序。这个也不难理解,就看这两者谁的cost更小,我们就会选择谁。

还是上面的例子,我们在query中显式要求按照revisionnumber进行排序:

我们可以看到这次,我们选择的是先哈希聚合,然后再对结果进行排序。

最后我们来看一下distinct操作,其实distinctgroup by是类似的,我们其实一般可以用group by来重写distinct,假如有index的话,我们显然可以直接使用流聚合操作。假如没有index,我们就需要使用distinct sort或者哈希聚合了。

可以看到这个例子中,就是使用了distinct sort,会排序并去除重复的行。

同样的,对于一个没有index的大表,我们可能会选择哈希聚合操作,如下所示:

至此,我们关于聚合操作的介绍就到这里结束了,下一章节我们会讲一讲join操作,敬请期待。


转载请注明出处:http://www.softlifelogging.com/?p=179&preview=true

更多精彩内容,敬请关注微信公众号:随手记生活

No Comments

Leave a Reply

Your email address will not be published.