2017-07-12 28 views
0

据我所知,聚集索引创建一个B树,实际数据存储在作为双向链表连接的树叶中。SQL服务器中聚簇索引扫描期间读取的实际表数据还是索引指针?

但是,如果存在索引扫描(从表中选择没有任何“where”子句的数据),那么SQL服务器是只读取索引指针(非叶节点)还是实际读取数据?

我的执行计划显示聚集索引扫描得到1 GB的数据,这与我的表大小几乎相同。根据我的理解,SQL索引扫描应该获取所有实际的表数据。我在这里错过了什么。

回答

0

聚集索引本身是表,所以表read..Index指针只是用于通过B树导航

0

聚集索引本身是实际的表...

如果直接创建一个表没有聚集索引,它被称为堆 - 这只是一些无组织(无序)的页面集。每个页面将指向前一页和下一页(双向链接列表)。

现在想象你该表创建一个聚集索引:现在

所有页面都存储在集群中指定的键的顺序 - >这些都是叶级页,并包含每一行中的实际数据。这些仍然使用双向链表。

此外,聚集索引结构将涉及上层的额外页面(可能超过一个层次),以便它们形成平衡树 - >这些是分支页面和根页面。仅从聚簇键获得的数据用作指向较低级别页面的指针。

这种形式使得SQL引擎可以容易地找到找到数据所需的页面(被称为SEEK操作),例如当您执行使用与集群密钥匹配的谓词的查询时,它将能够有效地查找确切的数据。

如果键不匹配,或者SQL知道该表足够小(或者即使它知道它几乎返回了整个表数据),也不必使用上层页面。它可能会决定直接进入叶级页面来扫描所有行并找出匹配的记录。记住双链表以指向上一页和下一页。

Bonus:即使指定了WHERE子句,也可能存在索引扫描,因为它无法使用seek或SQL思想,因此扫描的效率高于seek。

让我知道这是否有帮助。