【问题标题】:Is the actual table data read during clustered index scan in SQL server or just the index pointers?是在 SQL Server 中的聚集索引扫描期间读取的实际表数据还是只是索引指针?
【发布时间】:2017-12-17 04:24:02
【问题描述】:
我知道聚集索引创建一个 B-tree 并且实际数据存储在叶子的连接中作为一个双向链表。
但是当存在索引扫描(从表中选择数据而没有任何“where”子句)时,SQL 服务器是只读取索引指针(非叶节点)还是实际读取数据。
我的执行计划显示聚集索引扫描获得了 1 GB 的数据,这与我的表大小几乎相同。据我了解,SQL 索引扫描应该获取所有实际的表数据。我在这里错过了什么吗?
【问题讨论】:
标签:
sql
sql-server
sqlperformance
【解决方案1】:
聚集索引本身就是实际的表...
如果您直接创建一个没有聚集索引的表,它被称为堆 - 它只是一些无组织(未排序)的页面集。每个页面都将指向上一页和下一页(双向链表)。
现在假设您为该表创建了一个聚集索引:
所有页面现在都按照为集群指定的键的顺序存储 -> 这些是叶级页面,每行都包含实际数据。这些仍然使用双向链表。
另外,聚簇索引结构会在上层(可能不止一层)中包含额外的页面,从而形成一个平衡的树->这些是分支页面和根页面。仅从聚集键派生的数据用作指向较低级别页面的指针。
这种形式是为了让 SQL 引擎可以轻松找到查找数据所需的页面(称为 SEEK 操作),例如当您执行使用与集群键匹配的谓词的查询时,它将能够有效地定位确切的数据。
如果键不匹配,或者如果 SQL 知道该表足够小(或者即使它知道它返回几乎整个表数据),它就不必使用上层页面。它可能决定直接去叶级页面扫描所有行并找出匹配的记录。记住双链表指向上一页和下一页。
奖励:即使您指定了 WHERE 子句,也可能会进行索引扫描,因为它无法使用 seek 或 SQL 认为扫描比 seek 更有效。
如果这有帮助,请告诉我。
【解决方案2】:
聚集索引本身就是表,所以表被读取..索引指针仅用于在 BTree 中导航