您的位置:首页 > 其它

查询优化器内核剖析第七篇:执行引擎之数据访问操作---Scan

2013-02-28 17:32 411 查看
从本篇了开始的接下来的几篇文章将会介绍与执行引擎相关的知识。

执行引擎就是由大量的物理操作组成的(而这些物理操作又会去调用存储引起的相关方法),这些操作被查询处理器用来高效的执行我们的查询。

这里不要将查询处理器与查询优化器搞混淆,它们不是同一个东西。为了使得大家对相关的概念有一个清楚的认识,请看到下面这一个图:






20120813083152.png(19.21
K)

8/13/2012 8:48:36 AM

从图中,就可以一目了然的直到查询处理器与查询优化器之间的关系:
1.数据库基本上有两大部分组成:关系引擎,存储引擎。
2.我们这里所说的“查询处理器”就是图中的关系引擎,而查询优化器只是其中的一个部分。

我们最近将要介绍的“执行引擎”,就是上图中的“Query Executor”。在介绍执行引擎的过程中,我这里主要会着重的介绍几类在我们查询中常见的一些操作:数据访问,聚合,Join,还有并行操作。当然,在执行引擎中,还有更多的操作,如果大家感兴趣,可以去参看SQL
Server的联机丛书。

我们首先将会介绍给数据访问的几个操作:scan,seek,还有lookup。
相信大家对这些操作应该有所了解的,我这里稍微的提及一下:

Scan:这个操作会读取整个数据结构,这个数据结构可以是一个堆表,聚集索引,非聚集索引。
Seek:这个操作不会读取整个数据结构,而是直接通过索引定位到要读取的那一行。所以Seek操作只能发生在聚集索引与非聚集索引上。
:就是没有建立聚集索引的表,表中的数据没有按照顺序进行存储。一旦一个表建立了聚集索引,那么表中的数据就会按照聚集索引排序存储。

另外,非聚集索引可以建立在堆表上,也可以建立在还有聚集索引的表上。

我们通过下面的一个表做一下总结(看看不同的数据结构可以支持何种物理操作),然后迅速进入Scan操作的详细讲解。
数据结构
Scan
Seek
堆表
Table Scan
聚集索引
Clustered Index Scan
Clustered Index Seek
非聚集索引
Index Scan
Index Seek
还是和之前一样,我们从一个例子入手,这里依然使用示例数据库AdventureWorks。我们首先来看到一个Table
Scan的操作(也就是整表扫描)
,看到如下的查询:






20120813083257.png(5.74
K)

8/13/2012 8:48:36 AM

查看实际的执行计划,如下图:






20120813083329.png(13.23
K)

8/13/2012 8:48:36 AM

通过查看DatabaseLog表的定义,我们发现这个表是一个堆表,即,这个表没有聚集索引,如下所示:






20120813083826.png(14.92
K)

8/13/2012 8:48:36 AM

下面,我们再看一个Clustered Index Scan(聚集索引扫描)的例子,看到如下查询:






20120813083930.png(7.63
K)

8/13/2012 8:48:36 AM

执行计划如下如所示:






20120813084439.png(17.53
K)

8/13/2012 8:48:36 AM

通过查看Address表的定义,发现这个表确实还有聚集索引:






20120813084522.png(17.95
K)

8/13/2012 8:48:36 AM

可以上面的例子可以知道:
1.虽然同是进行了
Scan操作,但是因为表的一些特性不同,而最后选择的具体的物理操作Scan也不一样。
2.不管是Table Scan还是Clustered
Index Scan,它们都是对相应的数据结构进行了全部的扫描,不同的是:前者发生在堆表上,后者发生在含有聚集索引的表上。

下面,给大家看一个比较有意思的查询:






20120813084806.png(13.45
K)

8/13/2012 8:48:36 AM

执行计划如下:






20120813084849.png(17.86
K)

8/13/2012 8:48:36 AM

图中显示的是Index Scan,也就说,这个查询没有去扫描表的所有数据页,而是去扫描索引,这个成本小得多。之所以进行了这个操作,是因为在这个表上存在一个非聚集索引,定义如下:






20120813084925.png(17.20
K)

8/13/2012 8:48:36 AM

这个非聚集索引包含了我们查询中的两个字段:[City],[StateProvinceID]。又因为AddressID是这个表的聚集索引,对于一个有聚集索引的表而言,它的所有的非聚集索引都会包含一个对聚集索引的引用,这样是为了加快数据检索的速度(大家可以想想为什么?)。所以,我们上面查询中的三个操作都可以在索引页中找到,就没有必要去扫描底层的表了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐